Skip to content

Instantly share code, notes, and snippets.

@takehiko
Created June 4, 2018 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/c53d52762a4ca3f62c0bad861000f9ae to your computer and use it in GitHub Desktop.
Save takehiko/c53d52762a4ca3f62c0bad861000f9ae to your computer and use it in GitHub Desktop.
A solver of triangular subtraction problem
#!/usr/bin/env ruby
# trisub.rb : a solver of triangular subtraction problem
# by takehikom
# Usage:
# ruby trisub.rb
# ruby trisub.rb 4
# ruby trisub.rb 5
# ruby trisub.rb 6 # no answer
# ruby trisub.rb blank
# Depends on:
# UDデジタル教科書体; http://www.morisawa.co.jp/about/news/3681
def solve_trisub(n = 3)
max = n * (n + 1) / 2
a = (1..max).to_a
a.permutation(n) do |b|
c = 0
1.upto(n) do |s|
1.upto(n - s) do |t|
b << (b[c] - b[c + 1]).abs
c += 1
end
c += 1
end
if b.sort == a
print_trisub(b, n)
make_svg_trisub(b, n)
end
end
end
def print_trisub(b, n)
puts [b[0, n], b, b.sort].map {|i| i.inspect }.join(" => ")
end
def make_svg_trisub(b, n)
if Array === b
filename = "#{n}_#{b[0, n].join('-')}.svg"
else
filename = "#{n}_blank.svg"
end
side = 80
margin = 20
strokewidth = side * 0.025
fontsize = side * 0.8
width = height = side * n + margin * 2
code = <<"EOS"
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="#{width}" height ="#{height}">
<rect x="0" y="0" width="#{width}" height="#{height}" style="fill:#cfc;stroke:none" />
EOS
b = b.dup
c = 0
1.upto(n) do |s|
1.upto(n - s + 1) do |t|
x = side * (t - 1) + side * (s - 1) / 2 + margin
y = side * (s - 1) + margin
code += <<"EOS"
<rect x="#{x}" y="#{y}" width="#{side}" height="#{side}" style="fill:white;stroke:black;stroke-width:#{strokewidth}" />
EOS
if Array === b
x2 = x + side / 2 - ((Numeric === b[c] && b[c] >= 10 && b[c] != 11) ? side / 14 : 0)
y2 = y + side / 2 + side / 3
code += <<"EOS"
<text x="#{x2}" y="#{y2}" style="font-family:'UD Digi Kyokasho NK-R';font-size:#{fontsize}px;fill:black;stroke:none"><tspan style="text-align:center;text-anchor:middle;">#{b[c]}</tspan></text>
EOS
end
c += 1
end
end
code += <<"EOS"
</svg>
EOS
open(filename, "w").print code
end
if __FILE__ == $0
if /blank/ =~ ARGV.first
1.upto(5) do |n|
make_svg_trisub(nil, n)
end
exit
end
solve_trisub((ARGV.shift || 3).to_i)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment