小町算
Posted feedbacks - Nested
Flatten Hidden枝狩り一切無し。効率悪いと思ふ。
1 2 3 4 5 6 7 | require "mathn"
(5**8).times do |i|
s=("2".."9").inject("1") do |r,e|
r+=["","+","-","*","/"][i%5]+e;i/=5;r
end
puts s if eval(s)==100
end
|
とりあえず投稿。括弧は使わない版。結果は101通り出てきます。 (123 - 45 - 67 + 89) (1 * 2 - 3 + 4 - 5 + 6 + 7 + 89) (1 + 2 * 3 - 4 - 5 + 6 + 7 + 89) (1 - 23 + 4 * 5 + 6 + 7 + 89) (12 - 3 - 4 + 5 - 6 + 7 + 89) (1 + 2 + 3 * 4 - 5 - 6 + 7 + 89) (1 - 23 - 4 + 5 * 6 + 7 + 89) (1 * 2 / 3 + 4 * 5 / 6 + 7 + 89) (1 / 2 * 34 - 5 + 6 - 7 + 89) (12 + 3 + 4 + 5 - 6 - 7 + 89) (1 * 23 - 4 + 5 - 6 - 7 + 89) (12 / 3 + 4 * 5 - 6 - 7 + 89) (1 - 23 - 4 - 5 + 6 * 7 + 89) (1 * 2 - 3 + 4 + 56 / 7 + 89) (1 + 2 * 3 - 4 + 56 / 7 + 89) (12 + 3 + 4 - 56 / 7 + 89) (1 * 23 - 4 - 56 / 7 + 89) (123 + 4 - 5 + 67 - 89) (1 + 234 * 5 / 6 - 7 - 89) (12 + 3 * 45 + 6 * 7 - 89) (1 + 2 * 34 - 56 + 78 + 9) (1 + 2 + 3 - 4 + 5 + 6 + 78 + 9) (1 * 2 * 3 - 4 + 5 + 6 + 78 + 9) (1 * 2 + 3 * 4 + 5 - 6 + 78 + 9) (12 + 3 * 4 - 5 - 6 + 78 + 9) (1 * 2 * 3 * 4 - 5 - 6 + 78 + 9) (1 * 2 - 3 + 4 * 5 - 6 + 78 + 9) (1 + 2 + 3 * 4 * 5 / 6 + 78 + 9) (1 + 234 * 5 * 6 / 78 + 9) (1 + 2 * 3 + 4 + 5 + 67 + 8 + 9) (12 + 3 - 4 + 5 + 67 + 8 + 9) (1 - 2 + 3 * 4 + 5 + 67 + 8 + 9) (1 - 2 - 3 + 4 * 5 + 67 + 8 + 9) (12 * 3 - 4 * 5 + 67 + 8 + 9) (1 / 2 / 3 * 456 + 7 + 8 + 9) (1 + 23 - 4 + 56 + 7 + 8 + 9) (12 + 34 + 5 * 6 + 7 + 8 + 9) (1 - 2 - 3 + 45 + 6 * 7 + 8 + 9) (1 * 2 + 34 + 5 + 6 * 7 + 8 + 9) (12 + 34 - 5 + 6 * 7 + 8 + 9) (1 * 23 + 4 + 5 + 67 - 8 + 9) (1 + 2 + 34 - 5 + 67 - 8 + 9) (1 * 2 + 34 + 56 + 7 - 8 + 9) (1 + 23 * 4 + 5 - 6 + 7 - 8 + 9) (1 + 2 + 3 * 4 * 56 / 7 - 8 + 9) (12 + 3 * 4 + 5 + 6 + 7 * 8 + 9) (1 * 2 * 3 * 4 + 5 + 6 + 7 * 8 + 9) (12 - 3 + 4 * 5 + 6 + 7 * 8 + 9) (1 - 2 - 3 + 45 - 6 + 7 * 8 + 9) (1 * 2 + 34 + 5 - 6 + 7 * 8 + 9) (12 + 34 - 5 - 6 + 7 * 8 + 9) (12 - 3 - 4 + 5 * 6 + 7 * 8 + 9) (1 * 23 + 4 + 56 / 7 * 8 + 9) (1 * 23 * 4 - 56 / 7 / 8 + 9) (1 + 23 - 4 + 5 + 6 + 78 - 9) (1 * 2 + 3 + 4 * 5 + 6 + 78 - 9) (12 * 3 - 4 + 5 - 6 + 78 - 9) (1 * 2 + 3 - 4 + 5 * 6 + 78 - 9) (12 / 3 / 4 + 5 * 6 + 78 - 9) (123 + 45 - 67 + 8 - 9) (1 + 23 * 4 - 5 + 6 + 7 + 8 - 9) (123 - 4 - 5 - 6 - 7 + 8 - 9) (1 - 2 + 3 * 4 * 5 + 6 * 7 + 8 - 9) (123 + 4 * 5 - 6 * 7 + 8 - 9) (1 + 23 * 4 + 56 / 7 + 8 - 9) (1 * 2 + 3 + 45 + 67 - 8 - 9) (1 * 2 * 34 + 56 - 7 - 8 - 9) (12 / 3 + 4 * 5 * 6 - 7 - 8 - 9) (1 - 2 + 3 + 45 + 6 + 7 * 8 - 9) (1 - 2 + 3 * 4 * 5 - 6 + 7 * 8 - 9) (12 / 3 + 4 * 5 * 6 * 7 / 8 - 9) (1 + 2 + 3 - 45 + 67 + 8 * 9) (1 * 2 * 3 - 45 + 67 + 8 * 9) (1 - 2 - 34 + 56 + 7 + 8 * 9) (1 / 2 * 3 / 4 * 56 + 7 + 8 * 9) (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 * 9) (1 * 2 * 3 + 4 + 5 + 6 + 7 + 8 * 9) (1 + 23 - 4 - 5 + 6 + 7 + 8 * 9) (1 - 2 * 3 + 4 * 5 + 6 + 7 + 8 * 9) (12 * 3 - 4 - 5 - 6 + 7 + 8 * 9) (1 + 2 * 3 + 4 * 5 - 6 + 7 + 8 * 9) (1 - 2 * 3 - 4 + 5 * 6 + 7 + 8 * 9) (1 + 2 - 3 * 4 + 5 * 6 + 7 + 8 * 9) (1 + 2 * 3 * 4 * 5 / 6 + 7 + 8 * 9) (12 + 3 * 4 + 5 + 6 - 7 + 8 * 9) (1 * 2 * 3 * 4 + 5 + 6 - 7 + 8 * 9) (12 - 3 + 4 * 5 + 6 - 7 + 8 * 9) (1 - 2 - 3 + 45 - 6 - 7 + 8 * 9) (1 * 2 + 34 + 5 - 6 - 7 + 8 * 9) (12 + 34 - 5 - 6 - 7 + 8 * 9) (12 - 3 - 4 + 5 * 6 - 7 + 8 * 9) (1 - 2 * 3 - 4 - 5 + 6 * 7 + 8 * 9) (1 + 2 - 3 * 4 - 5 + 6 * 7 + 8 * 9) (1 + 2 + 3 - 4 * 5 + 6 * 7 + 8 * 9) (1 * 2 * 3 - 4 * 5 + 6 * 7 + 8 * 9) (1 + 23 - 4 + 56 / 7 + 8 * 9) (1 * 2 + 34 - 56 / 7 + 8 * 9) (1 - 2 - 3 + 4 * 56 / 7 + 8 * 9) (1 * 234 + 5 - 67 - 8 * 9) (1 + 234 - 56 - 7 - 8 * 9) (1 + 2 + 34 * 5 + 6 - 7 - 8 * 9)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | (use srfi-1)
(define (atom? x)
(not (or (null? x) (pair? x))))
(define (atom-list? ls)
(and (pair? ls) (atom? (car ls))))
(define (my-flatten ls)
(cond ((null? ls) '())
((pair? ls)
(cond ((atom? (car ls)) (list ls))
((atom-list? (car ls))
(append (list (car ls)) (my-flatten (cdr ls))))
(else
(append (my-flatten (car ls)) (my-flatten (cdr ls))))))
(else (list ls))))
(define (_ a b)
(cond ((< b 10) (+ (* a 10) b))
((< b 100) (+ (* a 100) b))
((< b 1000) (+ (* a 1000) b))
((< b 10000) (+ (* a 10000) b))
((< b 100000) (+ (* a 100000) b))
((< b 1000000) (+ (* a 1000000) b))
((< b 10000000) (+ (* a 10000000) b))
((< b 100000000) (+ (* a 100000000) b))
((< b 1000000000) (+ (* a 1000000000) b))
; (else #f)
))
(define ops '(_ + - * /))
(define (apply-op op x y)
(case op
((_) (_ x y))
((+) (+ x y))
((-) (- x y))
((*) (* x y))
((/) (/ x y))
))
(define (apply-rev-op op x y)
(case op
; ((_) (_ x y))
((+) (- x y))
((-) (+ x y))
((*) (/ x y))
((/) (* x y))))
(define (komachi n sum)
(define (append-op-n ls op n) (append ls (list op n)))
(define (1..k= k p)
; [1..k] = p となる組み合わせ
(if (= 1 k) ;
; 1 = 1 ; p!=1ならアウト
(if (= p 1) '((1)) '())
; [1..k-1] ?? k = p
(my-flatten (map (lambda (op) (1..k (- k 1) op k p)) ops))
))
(define (eval-exp exp)
(define (iter rest product)
(cond ((null? rest) product)
((eq? '* (car rest))
(iter (cddr rest) (* product (cadr rest))))
((eq? '/ (car rest))
(iter (cddr rest) (/ product (cadr rest))))
))
(iter (cdr exp) (car exp)))
(define (1..k?<..>= k op exp p)
; [1..k] op (exp) = p
(if (= 1 k)
(case op
((_)
(let1 exp* (cons (_ 1 (car exp)) (cdr exp))
(if (= (eval-exp exp*) p)
exp*
'())))
((+ -) ; 1 +- exp = p
(if (= (apply-op op 1 (eval-exp exp)) p)
(append (list 1 op) exp)
'()))
((* /)
(let1 exp* (append (list 1 op) exp)
(if (= (eval-exp exp*) p)
exp*
'())))
)
(case op
((_)
(my-flatten
(map (lambda (op2) (1..k?<..>= (- k 1) op2 (cons (_ k (car exp)) (cdr exp)) p)) ops)))
((+ -)
(map (lambda (x) (append x (list op) exp))
(my-flatten (1..k= k (apply-rev-op op p (eval-exp exp))))
))
((* /)
(my-flatten
(map (lambda (op2) (1..k?<..>= (- k 1) op2 (append (list k op) exp) p)) ops)))
)
))
(define (1..k k op n p)
; [1..k] op n = p となる組み合わせが全部ほしい
(if (= 1 k)
;k=1 : [1] op n = p
(case op
((_)
(if (= (_ 1 n) p) (list (_ 1 n)) '()))
((+ -)
(if (= (apply-op op 1 n) p) (list 1 op n) '()))
((*)
(if (= n p) (list 1 '* n) '()))
((/) '()) ; 1/n (n>1) cannot be p
)
;k>1
(case op
((_); [1..k-1] ?? k_n = p
(my-flatten (map (lambda (op2) (1..k (- k 1) op2 (_ k n) p)) ops)))
((+ -) ; [1..k] ± n = p ;
(map (lambda (x) (append-op-n x op n))
(my-flatten (1..k= k (apply-rev-op op p n)))))
((* /) ; [1..k] */ n = p :: [1..c] ? ([c+1..k] */ n) = p
(my-flatten (map (lambda (op2) (1..k?<..>= (- k 1) op2 (list k op n) p)) ops)))
; 結合則が加減算とは違う
)
))
(remove null? (1..k= n sum)))
(map print (komachi 9 100))
|
秒殺です % time gosh komachi.scm (123 - 45 - 67 + 89) (1 * 2 - 3 + 4 - 5 + 6 + 7 + 89) 中略 (1 + 234 - 56 - 7 - 8 * 9) (1 + 2 + 34 * 5 + 6 - 7 - 8 * 9) real 0m0.775s user 0m0.758s sys 0m0.015s
pythonでナイーブな実装。 括弧なしで101個でした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def komachi():
num = range(1,10)
ope = ["",".0+",".0-",".0*",".0/"]
c = 1
for x in xrange(5**8):
formula = str(num[0])
for n in range(1,9):
formula += ope[x%5] + str(num[n])
x /= 5
if eval(formula) == 100:
print formula,c
c += 1
komachi()
|
「C# には eval が無いなぁ。動的コンパイルでもしようかな。あ待てよアレがあったな」 ということで C#2.0 + IronPython1.1 です。ところてんさんの #4728 を参考に、Python のコードを片っ端から生成して IronPython で Execute しています。komachi 関数は C# 側で作成。括弧なしで 101 個を、6分程度(orz)で調べ上げます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | using System;
using System.Collections.Generic;
using IronPython;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Calls;
class Program {
static void Main() {
PythonEngine python = new PythonEngine();
EngineModule module = python.CreateModule();
Dictionary<string, object> locals = new Dictionary<string, object>();
int count = 0;
locals["komachi"] = new CallTarget2(delegate(object obj, object obj2) {
if (obj2.Equals(100.0)) {
count++;
Console.WriteLine(obj + " = " + obj2);
}
return null;
});
DateTime before = DateTime.Now;
foreach (string code in GenPythonCode()) {
python.Execute(code, module, locals);
}
Console.WriteLine("time: {0}", DateTime.Now - before);
Console.WriteLine("total: {0}", count);
}
static IEnumerable<string> GenPythonCode()
{
string[] ops = { "", ".0+", ".0-", ".0*", ".0/" };
for (int i = 0; i < Math.Pow(ops.Length, 8); i++) {
string code = "1";
int j = i;
foreach (char num in "23456789") {
code += ops[j % ops.Length] + num;
j /= ops.Length;
}
yield return string.Format("komachi(\"{0}\", {0})", code + ".0");
}
}
}
|
パーサコンビネータでパーサを作ってナイーブに。 解答は101個です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import scala.util.parsing.combinator.{Parsers, ImplicitConversions, ~, mkTilde}
import scala.util.parsing.combinator.syntactical.StdTokenParsers
import scala.util.parsing.combinator.lexical.StdLexical
object Komachi extends StdTokenParsers with Application{
type Tokens = StdLexical ; val lexical = new StdLexical
lexical.delimiters ++= List("+","-", "*", "/")
def expr = term*("+" ^^ {(x: double, y: double) => x + y}
| "-" ^^ {(x: double, y: double) => x - y})
def term = factor*("*" ^^ {(x: double, y: double) => x * y}
| "/" ^^ {(x: double, y: double) => x / y})
def factor: Parser[double] = numericLit ^^ (_.toDouble)
((List(List[String]())) /: List.make(8, List("+", "-", "*", "/", ""))){
for(i <-_; j <-_) yield j::i
}.foreach{fs =>
val s = (new StringBuilder("1") /: (2 to 9)){(s,i) =>
s.append(fs(i-2)).append(i)
}.toString
if(expr(new lexical.Scanner(s)).get == 100.0) println(s)
}
}
|
#4725 を参考にしました。printはRhinoのprintで。
重いので、ブラウザでは動かさないように。
重いので、ブラウザでは動かさないように。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function komachi() {
var list = Array.prototype.slice.apply(arguments, [0]);
var right = list.pop();
var operator = ["", "+", "-", "*", "/"];
var n = Math.pow(operator.length,list.length-1);
for(var i=0; i<n; i++) {
var exp = [list[0]];
var o = (n+i).toString(5);
for(var j=1, ii=i; j<list.length; j++) {
exp.push(operator[o.slice(j,j+1)]);
exp.push(list[j]);
ii = Math.floor(i/5);
}
if(eval(exp.join("")) == right) print(exp.join("") + '=' + right);
}
}
print("begin");
komachi(1,2,3,4,5,6,7,8,9,100);
print("end");
|
解答101個で4分弱でした。
ナイーブに全探索。
opparseで演算子順位文法を使って式をRPNに変換し、calcで計算してます。
opsの定義を変えれば演算子を増やしたり優先順位を買えたりできます。同じ優先度の演算子は左結合。
opparseで演算子順位文法を使って式をRPNに変換し、calcで計算してます。
opsの定義を変えれば演算子を増やしたり優先順位を買えたりできます。同じ優先度の演算子は左結合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import Numeric
data Item a b = Value a | Op (a->a->a) b [Char]
cat a b = a*10+b
ops :: [Item Double Integer]
ops = [Op cat 2 "", Op (+) 0 "+", Op (-) 0 "-", Op (*) 1 "*", Op (/) 1 "/"]
opparse [] _ vs = reverse vs
opparse (op:ops) (i:is) vs = opparse ops is $ push op (Value i) vs
push op@(Op o p _) v (op'@(Op o' p' _):vs)
| (p <= p') = (op:v:op':vs)
| otherwise = (op':push op v vs)
push op v vs = op:v:vs
calc [a] [] = a
calc ns ((Value a):vs) = calc (a:ns) vs
calc (a:b:ns) ((Op op _ _):vs) = calc ((op b a):ns) vs
calc _ _ = error "invalid stack state"
showFormula ops = "1" ++ rec [2..] ops where
rec _ [] = ""
rec (i:is) ((Op _ _ n):ops) = n ++ (showInt . round) i (rec is ops)
genops 0 = [[]]
genops n = [o:os | o <- map (ops!!) [0..4], os <- genops (n-1)]
komachi n = [ops | ops <- genops n, test 100 ops] where
test sum ops = abs (sum - (calc [] $ opparse ops [2..] [Value 1])) <= 1.0e-10
main = putStr $ unlines $ map showFormula $ komachi 8
|
高階関数と有理数を使って書き直してみました。 一部私好みに書き換えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import Ratio
data Item a b c = Value a | Op (b->b->b) c String
cat a b = a*10+b
ops :: [Item Integer Rational Integer]
ops = [Op cat 2 "", Op (+) 0 "+", Op (-) 0 "-", Op (*) 1 "*", Op (/) 1 "/"]
opparse ops = reverse $ foldl push [Value 1] (zip ops $ map Value [2..])
push (op'@(Op o' p' _):vs) opv@(op@(Op o p _), v)
| p <= p' = op:v:op':vs
| otherwise = op':push vs opv
push vs (op, v) = op:v:vs
calc vs = head $ foldl g [] vs where
g ns (Value a) = a%1:ns
g (a:b:ns) (Op op _ _) = op b a:ns
g _ _ = error "invalid stack state"
showFormula ops = concat $ ["1"] ++ zipWith (\(Op _ _ n) i -> n ++ show i) ops [2..]
genops n = sequence $ replicate n ops
komachi n = filter (test 100) $ genops n where
test sum ops = sum == (calc $ opparse ops)
|
とりあえず適当に全探索。候補を5進8桁の整数と同一視して dotimes で回してます。結果は101 件、CLISP で 16 秒でした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | (defun apply-op (op x y)
(case op
(#\+ (+ x y))
(#\- (- x y))
(#\* (* x y))
(#\/ (/ x y))
(#\SPACE (+ (* 10 x) y))
(t 't)))
(defun precedence (op) (case op ((#\+ #\-) 1) ((#\* #\/) 2) (t 3)))
(defun precedence< (op1 op2) (< (precedence op1) (precedence op2)))
(defun eval-string (s)
(loop with vstack and opstack
for c across s
if (digit-char-p c) do
(push (parse-integer (string c)) vstack)
else if #1=(or (null opstack) (precedence< (car opstack) c)) do
(push c opstack)
else do
(loop until #1# do
#2=(setf vstack
(cons (apply-op (pop opstack) (cadr vstack) (car vstack))
(cddr vstack))))
(push c opstack)
finally
(loop for op in opstack do #2#)
(return (car vstack))))
(defun komachi ()
(let ((s (copy-seq "1 2 3 4 5 6 7 8 9")))
(dotimes (x (expt 5 8))
(dotimes (i 8)
(setf (elt s (+ i i 1)) (elt " +-*/" (rem (floor x (expt 5 i)) 5))))
(if (= (eval-string s) 100) (write-line s)))))
|
順当な遅さです。
1 2 3 4 5 6 7 8 9 10 11 | # -*- coding: utf-8 -*-
from __future__ import division
import re
E = '1%s2%s3%s4%s5%s6%s7%s8%s9==100'
A = ['', '+', '-', '*', '/']
F = lambda n: [[i] + l for i in A for l in F(n-1)] if n > 1 else [[i] for i in A]
R = lambda s: s.replace('+', u'+').replace('-', u'-').replace('*', u'×').replace('/', u'÷').replace('==', u'=')
print '\n'.join([R(E % tuple(l)) for l in F(8) if eval(E % tuple(l))])
|
Javaでは、evalがないので自前でParseを行って計算してみました。
括弧対応なしで、約1秒で 101通りの結果がでました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | import java.util.ArrayList;
import java.util.List;
public class Sample104 {
public static void komachi(int[] lhs, int rhs) {
if (lhs.length == 0) return;
List<Term> expression = new ArrayList<Term>();
expression.add(new TermValue(lhs[0]));
for (int index = 1; index < lhs.length; index++) {
List<Term> work = new ArrayList<Term>(expression);
expression.clear();
for (Term term: work) {
List<Term> list = createTerm(term, lhs[index]);
expression.addAll(list);
};
}
int counter = 1;
for (Term term: expression) {
if (term.getValue() == rhs) {
System.out.println(counter++ + ": " + term.toString() + " = " + rhs);
}
}
}
private static List<Term> createTerm(Term lhs, int r) {
List<Term> result = new ArrayList<Term>();
Operator[] operators = Operator.values();
for (int index = 0; index < operators.length; index++) {
result.add(new TermData(operators[index], lhs, new TermValue(r)));
}
return result;
}
public enum Operator {
None {
public int getPriority() { return 10; }
public double operate(double lhs, double rhs) { return lhs * 10 + rhs; }
public String toString() { return ""; }
},
Plus {
public int getPriority() { return 1; }
public double operate(double lhs, double rhs) { return lhs + rhs; }
public String toString() { return "+"; }
},
Minus {
public int getPriority() { return 1; }
public double operate(double lhs, double rhs) { return lhs - rhs; }
public String toString() { return "-"; }
},
Times {
public int getPriority() { return 2; }
public double operate(double lhs, double rhs) { return lhs * rhs; }
public String toString() { return "*"; }
},
Divide {
public int getPriority() { return 2; }
public double operate(double lhs, double rhs) { return lhs / rhs; }
public String toString() { return "/"; }
};
public abstract int getPriority();
public abstract double operate(double lhs, double rhs);
}
private static interface Term {
public boolean isOperate();
public double getValue();
}
private static class TermValue implements Term {
public final int value;
public TermValue(int val) {
value = val;
}
public boolean isOperate() { return false; }
public double getValue() {
return value;
}
public String toString() { return String.valueOf(value); }
}
private static class TermData implements Term {
public final Operator op;
public final Term lhs;
public final Term rhs;
/**
* 右辺は追加分と考えて、演算子の順序に従ってデータを正規化します。
*/
public TermData(Operator o, Term l, Term r) {
Operator operator = o;
Term lterm = l;
Term rterm = r;
if (l.isOperate()) {
TermData data = (TermData) l;
if (operator.getPriority() > data.op.getPriority()) {
rterm = new TermData(operator, data.rhs, rterm);
lterm = data.lhs;
operator = data.op;
}
}
op = operator;
lhs = lterm;
rhs = rterm;
}
public boolean isOperate() { return true; }
public double getValue() {
return op.operate(lhs.getValue(), rhs.getValue());
}
public String toString() {
return lhs.toString() + op.toString() + rhs.toString();
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
komachi(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, 100);
System.out.println();
long end = System.currentTimeMillis();
System.out.println("elipse: " + (end - start) + "(ms)");
}
}
|
アルゴリズム的には一番月並み。MacBook Pro 2.33GHz で12秒。
#あ、関数名が微妙に
Dan the Perl Monger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/local/bin/perl
use strict;
use warnings;
use B::Deparse;
sub komanechi {
for my $i ( 1 .. 5**8 ) {
my $formula = 1;
for my $n ( 2 .. 9 ) {
$formula .= ( '', qw{+ - * /} )[ $i % 5 ] . $n;
$i /= 5;
}
next if 100 != eval $formula;
print "$formula\n";
}
}
komanechi;
|




dpp
#4509()
Rating0/2=0.00
古典的なパズルである小町算を解くプログラムを作成してください。
小町算とは:
1□2□3□4□5□6□7□8□9=100
四角の中に、空白、+、-、×、÷のいずれかを一つ入れ、等式が成り立つようにするパズルです。
解答例:
1-2-3+4×56÷7+8×9=100
1+234×5÷6-7-89=100
参考: http://ja.wikipedia.org/wiki/%E5%B0%8F%E7%94%BA%E7%AE%97
手元で20数行ほどのPythonスクリプトを書いてみたところ、101個の解答が得られました。
[ reply ]