Last active
December 23, 2015 09:09
-
-
Save takehiko/6613014 to your computer and use it in GitHub Desktop.
Parity Problem Generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# -*- coding: utf-8 -*- | |
# ppg.rb : Parity Problem Generator | |
# by takehikom (http://d.hatena.ne.jp/takehikom/) | |
# Usage: | |
# ruby ppg.rb | |
# ruby ppg.rb 3 | |
# 遊び方 | |
# どの行・どの列も,すべて偶数または奇数となるよう, | |
# 反転させるべき場所(1箇所だけ)を見つけてください. | |
# 偶数か奇数かは,問題ごとにランダムです. | |
# 引数なしで実行した場合,最初に問題が表示されます.Enterのみを押せば | |
# 解答,そして次の問題に移り(無限ループ),qとEnterを押せば終了します. | |
# 引数(整数値)をつけて実行した場合,その数だけ,問題と解答を出力します. | |
module ParityProblem | |
class Board | |
def initialize(h = nil) | |
if h.nil? | |
h = { | |
:width => 6 + rand(3), | |
:height => 4 + rand(3), | |
:even => rand(2) == 0, | |
} | |
end | |
@width = h[:width] || 6 | |
@height = h[:height] || 6 | |
@even = h[:even] || false | |
@invert = [rand(@width), rand(@height)] | |
init_table_for_output | |
generate_board | |
end | |
def to_s(aa = [@board]) | |
aa.map! {|ary| ary.map {|item| bin_to_str(item)}} | |
if aa.size == 1 | |
aa.first.join("\n") + "\n" | |
else | |
aa1 = aa.shift | |
aa1.zip(*aa).map {|item| item.join(@s[:to])}.join("\n") + "\n" | |
end | |
end | |
def print_question | |
print to_s([create_corrupt_board]) | |
end | |
def print_question_answer | |
print to_s([create_corrupt_board, create_corrupt_board(2), @board]) | |
end | |
private | |
def init_table_for_output | |
if /jp/i =~ ENV["LANG"] | |
@s = { | |
0 => '□', | |
1 => '■', | |
2 => '*', | |
:to => ' → ' | |
} | |
else | |
@s = { | |
0 => '0', | |
1 => '1', | |
2 => '*', | |
:to => ' => ' | |
} | |
end | |
end | |
def generate_board | |
@board = Array.new(@height - 1) do | |
Array.new(@width - 1) do | |
rand(2) | |
end | |
end | |
if $DEBUG | |
puts "#### step 1 ####" | |
print to_s([@board]) | |
end | |
@board.map! do |item| | |
item + [(item.reduce(:+) + (@even ? 0 : 1)) % 2] | |
end | |
if $DEBUG | |
puts "#### step 2 ####" | |
print to_s([@board]) | |
end | |
@board << @board.transpose.map do |item| | |
(item.reduce(:+) + (@even ? 0 : 1)) % 2 | |
end | |
if $DEBUG | |
puts "#### step 3 ####" | |
print to_s([@board]) | |
puts | |
end | |
@board | |
end | |
def bin_to_str(ary) | |
ary.map {|c| @s[c]}.join("") | |
end | |
def create_corrupt_board(val = nil) | |
ary = Marshal.load(Marshal.dump(@board)) | |
ary[@invert[1]][@invert[0]] = val || (1 - ary[@invert[1]][@invert[0]]) | |
ary | |
end | |
end | |
class Manager | |
def self.print_question_answer | |
board = ParityProblem::Board.new | |
board.print_question_answer | |
end | |
def self.start | |
loop do | |
board = ParityProblem::Board.new | |
print("\033[2J\033[0;0H") | |
board.print_question | |
break if /^q/i =~ gets | |
print("\033[2J\033[0;0H") | |
board.print_question_answer | |
break if /^q/i =~ gets | |
end | |
end | |
end | |
end | |
if __FILE__ == $0 | |
if ARGV.empty? | |
ParityProblem::Manager.start | |
else | |
ARGV.shift.to_i.times do | |
ParityProblem::Manager.print_question_answer | |
puts | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment