18

在 Google Code Jam 2009第 1B 轮中,有一个称为决策树的问题,它为自己提供了相当有创意的解决方案。

发布您的最短解决方案;假设您不只是为了解决这个问题而创建一种新语言,我会以半频率将 Accepted Answer 更新为当前最短的条目。:-P

目前排名:

4

23 回答 23

33

sed 1554 个字符(纯)/281 个(带 bc)

是的,认真的。

用法:sed -r -f thisfile.sed < input.in > output.out

(适用于 GNU sed)

1d
/ /!{x
s/^$/Case #Y:/
:i
s/9Y/Y0/
ti
s/#Y/#0Y/
s/:/:0123456789/
s/(.)Y(.*):[0-9]*\1(.).*/\3\2Y:/
x
G
s/.*\n|Y//gp
z
:p
N
/[()]/s/ |\n//g
y/()/JK/
tp
H
d}
G
s/\n[^J]*/ %/
s/[^JK]*$//
:c
s/J1?([.-9]+)(.*)K/\2@\1/
/%@/by
:b
/J/s/T//
s/J([^JK]*)K/TC\1B/
tb
/ (.+) .*%\1C/{s/%[^C]*/%/
s/T.*B//
by}
s/%.*T/%/
:y
y/CB/JK/
tc
s/.\.0*\b//g
:r
/@.*@/{s/\w*@\w*$/C&B/
s/C(\w)(.*B)/\1C\2~/
s/"[^"]*/&0/g
:t
s/(\w)(C.*)(\w)B(.*~)/\1\2B\3\4\1\3/
T
s/~(10|2[01]|3[0-2]|4[0-3]|5[0-4]|6[0-5]|7[0-6]|8[0-7]|9.)/&Q/
s/(.)(.)Q/\2\1/
s/~0\w/`00/
s/~1\B/`0/
s/~22/`04/
s/~23/`06/
s/~24/`08/
s/~33/`09/
s/~25/`10/
s/~26|~34/`12/
s/~27/`14/
s/~28|~44/`16/
s/~29|~36/`18/
s/~35/`15/
s/~45/`20/
s/~37/`21/
s/~38|~46/`24/
s/~55/`25/
s/~39/`27/
s/~47/`28/
s/~56/`30/
s/~48/`32/
s/~57/`35/
s/~49|~66/`36/
s/~58/`40/
s/~67/`42/
s/~59/`45/
s/~68/`48/
s/~77/`49/
s/~69/`54/
s/~78/`56/
s/~79/`63/
s/~88/`64/
s/~89/`72/
s/~99/`81/
s/`(.)(.)/~\1'\2/
bt
:
s/(~.)'/\1/
s/..'/K&/
/K/bk
:v
s/=(,?.)'/\1/
s/,/1'/
t
s/B(.*)~/\1B"/
tr
s/"(\w*)0/A\1/g
/A.*A/{s/A[^A]*$/J&K/
:k
s/([^A])(J.*)([^A])K/\2K\1\3/
s/K(10|2[01]|3[0-2]|4[0-3]|5[0-4]|6[0-5]|7[0-6]|8[^9]|9.)/&Q/
s/(.)(.)Q/\2\1/
s/K0/=/
s/K11/=2/
s/K12/=3/
s/K13|K22/=4/
s/K14|K23/=5/
s/K15|K24|K33/=6/
s/K16|K25|K34/=7/
s/K(17|26|35|44)/=8/
s/K(18|27|36|45)/=9/
s/K(19|28|37|46|55)/W0/
s/K(29|38|47|56)/W1/
s/K(39|48|57|66)/W2/
s/K49|K58|K67/W3/
s/K59|K68|K77/W4/
s/K69|K78/W5/
s/K79|K88/W6/
s/K89/W7/
s/K99/W8/
s/W/=,/
/'/bv
s/\b=/K:/
tk
s/[:JK]A?//g
s/,/,0123456789GF/
s/(.),.*\1(.).*F/\2/
s/G/,0/
tk}
/A.*A/bv}
s/\w*C.*A//
tr
s/.*@/./

此解决方案省略了小数点前的前导零,并且不处理答案为 1.00 的情况。幸运的是,GCJ 法官接受了缺少零的情况,并且没有任何案例的答案是 1.00。

要包括前导零,请将最后一行更改为s/.*@/0./; 并处理 1.00 案例,附加行s/^$/1/.

这是一个将乘法外包给 bc 的解决方案:

1d
/ /!{x
s/\n.*//
s/.*/echo 0&+1|bc/e
x
g
s/.*/Case #&:/p
:p
N
/[()]/s/ |\n//g
y/()/JK/
tp
H
d}
G
s/\n[^J]*/ %/
s/[^JK]*$//
:c
s/J([.-9]+)(.*)K/\2*\1/
/%\*/s/.*%.(.*)/echo \1|bc -l/e
:b
/J/s/T//
s/J([^JK]*)K/TC\1B/
tb
/ (.+) .*%\1C/{s/%[^C]*/%/
s/T.*B//
b}
s/%.*T/%/
:
y/CB/JK/
tc
于 2009-10-03T00:27:08.487 回答
16

Perl 107 个字符

say("Case #$_:"),
$_=eval"''".'.<>'x<>,
s:[a-z]+:*(/ $&\\s/?:g,s/\)\s*\(/):/g,
eval"\$_=<>;say$_;"x<>for 1..<>

易读的换行符;它们都不是必需的或计算在内。

它使用仅在最新版本的 Perl 中发现的功能,因此请使用perl -M5.010或更高版本运行。

我曾经也是一个 Perl 菜鸟,所以这和 ruby​​ 几乎一样。原始版本 126 个字符,由 peutri 优化。

反向链接:

字对齐 - 电源编程

于 2009-09-18T02:59:51.043 回答
14

百合池:212 个字符

疯狂!荒谬至极!!LilyPond 凭借其内置的 Scheme 解释器,超过了 Scheme 超过 50 个字节!穿着紧身衣的神圣杂技飞行驼鹿!!

x=#lambda
w=#read
#(letrec((v(x(a)(map a(iota(w)1))))(c(x(f q)(*(car q)(if(any list? q)(c
f((if(memq(cadr q)f)caddr cadddr)q))1)))))(v(x(i)(w)(set! @(w))(format
#t"Case #~a:
~{~y~}"i(v(x i(w)(c(v(x i(w)))@)))))))

用法:lilypond thisfile.ly <input.in >output.out 2>/dev/null

感谢 cky编写了基于此的 Scheme 解决方案,尽管这个版本现在有很大的不同。说真的,虽然,该计划可以进一步打高尔夫球......

于 2009-10-18T07:01:25.470 回答
12

PostScript:170(常规)/160(ASCII85)/121(二进制)

到目前为止,我最短的(常规)PostScript 解决方案,前提是您将输入文件重命名为“r”(170 个字符,包括换行符);使用 GhostScript 特定的过程 ( =only):

1[/:{repeat}/!{exch token{\ exch known{/<>}if]pop]]3 index mul
!}if}(]){token pop}/?(r)(r)file([){?]}>>begin
1[{(Case #)2{=only}:(:)=[/|[def[{[/\<<[{[/}:>>def |]! =}:}for

用法:cp input.in r; gs -q -dNOPROMPT -dNODISPLAY -dBATCH thisfile.ps > output.out

这是121 字节的二进制版本(反斜杠和不可打印的字符转义):

1[/!{\x92>\x92\xab{\\\x92>\x92`\x92p{]\x92u}if]]3\x92X\x92l!}if}(]){\x92\xab\x92u}/r(r)\x928\x92A([){r]}>>\x92\r1[{(Case #)\x92v=only[/:\x928[\x923=[{[/\\<<[{[/}\x92\x83>>\x923:]! =}\x92\x83}\x92H

如果不允许 ASCII 可打印范围之外的字符,PS 具有内置的二进制源的 ASCII85 编码。因此,我们在所有 ASCII 可打印字符中都有以下160 字节的解决方案:

1[([){r]}/r(r)<~OuSUj0-P\*5*Dsn>`q:6@$5JU?'9>YBkCXV1Qkk'Ca"4@Apl(5.=75YP')1:5*?@0>C.bc@<6!&,:Se!4`>4SH!;p_OuQ[/1Herh>;'5D4Bm/:07B"95!G,c3aEmO4aiKGI?I,~>cvx exec
于 2009-09-16T14:28:21.370 回答
11

红宝石在 132

由狮子座改进。换行是必不可少的。

def j
'1
'..gets
end
j.map{|c|s=j.map{gets}*''
puts"Case #%d:"%c,j.map{gets;eval s.gsub(/[a-z]+/,'*(/ \&\b/?').gsub /\)\s*\(/,'):'}}

红宝石在 136

def j;1..gets.to_i;end;j.map{|c|m=j.map{gets}*"";puts"Case ##{c}:";j.map{gets;p eval m.gsub(/[a-z]+/,'*(/ \0\s/?').gsub /\)\s*\(/,'):'}}

我刚刚了解到 *"" 等同于 .join""。也意识到地图可以在一些地方使用

红宝石 150

1.upto(gets.to_i){|c|m=eval("gets+"*gets.to_i+"''");puts"Case ##{c}:";1.upto(gets.to_i){gets;p eval m.gsub(/[a-z]+/,'*(/ \0\s/?').gsub /\)\s*\(/,'):'}}

我只是 ruby​​ 的菜鸟,所以可能还有很大的改进空间

于 2009-09-17T18:55:05.943 回答
9

192 年的 Python

import re;S=re.sub;R=raw_input;I=input;c=0;exec r"c+=1;L=S('\) *\(',')or ',S('([ az]+)','*(\' \\1 \'in a and',eval(('+R()'*I('Case #%s:\n'%c))[1:] )));exec'a=R()+\'\';​​打印 eval(L);'*I();"*I()
于 2009-09-17T04:07:55.207 回答
7

Common Lisp,199 字节

每 80 个字符换行一次:

(defun r()(read))(dotimes(i(r))(format t"~&Case #~D:"(1+ i))(r)(set'z(r))(dotime
s(a(r))(r)(print(do((g(mapcar'read(make-list(r))))(p 1(*(pop c)p))(c z(if(find(p
op c)g)(car c)(cadr c))))((not c)p)))))

间隔和缩进:

(defun r () (read))
(dotimes (i (r))
  (format t "~&Case #~D:" (1+ i))
  (r)
  (set 'z (r))
  (dotimes (a (r))
    (r)
    (print
      (do ((g (mapcar 'read (make-list (r))))
           (p 1 (* (pop c) p))
           (c z (if (find (pop c) g)
                    (car c)
                    (cadr c))))
          ((not c) p)))))
于 2009-09-16T15:09:09.727 回答
6

C - 346 字节

使用 gcc -w 编译

#define N{int n=atoi(gets(A));for(;n--;)
T[999];F[99];char*t,*f,*a,A[99];float p(){float
d,m=1;for(;*t++^40;);sscanf(t,"%f %[^ (]",&d,A);if(*A^41){for(f=F;m**f;){for(;*f&&*f++^32;);for(a=A;*a&&*f==*a;f++,a++);m=*a||*f&64;}d*=!m*p()+m*p();}return
d;}main(I)N{printf("Case #%d:\n",I++);t=T;N
for(gets(t);*++t;);}N gets(F),t=T,printf("%f\n",p());}}}
于 2009-09-30T22:20:25.677 回答
6

196 字节的 JavaScript

r='replace'
q=readline
for(n=0,t=q();t-n++;){for(print('Case #'+n+':'),d='',x=q();x--;d+=q());for(x=q();x--;)print(eval(d[r](/([a-z]+)/g,'*({'+q()[r](/ /g,':1,z')+':1}.z$1?')[r](/\) *\(/g,'):')))}

用法:$ smjs thisfile.js <input.in

由 Hyperlisk 贡献。

于 2009-10-05T01:58:56.930 回答
6

弧线,143154人物

与 CL 非常相似,但 Arc 肯定有简洁的标识符。每 40 个字符包装一次:

(for i 1((= r read))(prn"Case #"i":")(r)
(= z(r))(repeat(r)(r)(loop(= g(n-of(r)(r
))c z p 1)c(= p(*(pop c)p)c(if(pos(pop c
)g)c.0 cadr.c)))prn.p))

缩进:

(for i 1 ((= r read))
  (prn "Case #" i ":")
  (r)
  (= z (r))
  (repeat (r)
    (r)
    (loop (= g (n-of (r) (r))
             c z
             p 1)
       c
       (= p (* (pop c) p)
          c (if (pos (pop c) g)
                (c 0)
                (cadr c))))
    (prn p)))

反向链接:字对齐 - 电源编程

于 2009-10-08T22:25:04.790 回答
5

314 中的 PHP

<?php function q(){return trim(fgets(STDIN));}for($n=q($x=0);$x++<$n;){for($s=q($t='');$s--;$t.=q());echo"Case #$x:\n";for($z=q();$z--;){$l=explode(' ',q());$l[0]=0;printf("%f\n",eval('return'.preg_replace(array('/\(/','/(\w+),/','/(\d\)*),\((\d)/','/^./'),array(',(','*(in_array("$1",$l,1)?','$1:$2'),$t).';'));}}
于 2009-10-03T02:24:43.633 回答
4

福兰- 381

另存为a.F95
编译f95 a.F95

#define _ ENDDO
#define A READ(t(k:l-1),*),a
#define Q j=1,n;READ"(A)",s
#define R READ*,n;DO
#define S k+SCAN(t(k:),'()')
CHARACTER(999)s,t,u;R i=1,n;t="";PRINT"('Case #'i0':')",i
R Q;t=TRIM(t)//s;_;R Q;d=1;k=1;DO;k=S;l=S-1
IF(t(l:l)>"(")EXIT;A,u;d=d*a;k=l;m=0
IF(INDEX(s," "//TRIM(u)//" ")>0)CYCLE;DO;IF(')'>t(k:k))m=m+2;m=m-1;k=k+1
IF(1>m)EXIT;k=S-1;_;_;A;d=d*a;PRINT*,d;_;_;END

通过使用默认格式,每个结果以 2 个空格开头,但 google 判断允许。感谢谷歌评委!

扩展版

CHARACTER(999)s,t,u
READ*,n
DO i=1,n
    t=""
    PRINT"('Case #'I0':')",i
    READ*,n
    DO j=1,n
        READ"(A)",s
        t=TRIM(t)//s
    ENDDO
    READ*,n
    DO j=1,n
        READ"(A)",s
        d=1
        k=1
        DO
            k=k+SCAN(t(k:),'()')
            l=k+SCAN(t(k:),'()')-1
            IF(t(l:l)>"(")THEN
                READ(t(k:l-1),*),a
                d=d*a
                PRINT*,d
                EXIT
            ELSE
                READ(t(k:l-1),*),a,u
                d=d*a
                k=l
                m=0
                IF(INDEX(s," "//TRIM(u)//" ")>0)CYCLE
                DO
                    IF(')'>t(k:k))m=m+2
                    m=m-1
                    k=k+1
                    IF(1>m)EXIT
                    k=k+SCAN(t(k:),'()')-1
                ENDDO
            ENDIF
        ENDDO
    ENDDO
ENDDO
END
于 2009-10-06T22:17:26.607 回答
3

467 字节的 Java

这使用了 java 6 中包含的 javascript 解释器。

import java.util.*;class D{static{Scanner c=new
Scanner(System.in);int n=c.nextInt(),i=0,l;while(i++<n){l=c.nextInt();String
s="(";while(l-->=0)s+=c.nextLine();System.out.println("Case #"+i+":");l=c.nextInt();while(l-->0)try{c.next();System.out.println(new
javax.script.ScriptEngineManager().getEngineByName("js").eval(s.replace(")","))").replaceAll("\\) *\\(",":(").replaceAll("[a-z]+","*(/ $0 /.test('"+c.nextLine()+" ')?")));}catch(Exception
x){}}System.exit(0);}}

感谢 Varan、Chris 和 pfn(间接地)帮助我缩短它。
请参阅我的其他(甚至更短!)java 答案。

于 2009-09-27T22:12:13.700 回答
3

Haskell,312 个字符

这是 Haskell 的另一种方法。我把肮脏的工作留给了前奏曲lex。环绕它的是Text.ParserCombinators.ReadP. 单独导入它需要 36 个字符——啊!

解析器是一个Features -> SExp -> Cuteness函数,它省去了quibble/yairchu 的解决方案中的大部分类型声明。

import Text.ParserCombinators.ReadP
main=f(\t->do putStrLn$"Case #"++show t++":";s<-r g;r$print.fst.head.($id=<<s).readP_to_S.d.tail.words=<<g)
d x=do"("<-e;w<-e;c<-do{f<-e;y<-d x;n<-d x;u$if elem f x then y else n}<++u 1.0;e;u$c*read w
f x=do n<-g;mapM x[1..read n]
e=readS_to_P lex
r=f.const
g=getLine
u=return

它曾经使用 Control.Monad 的joinforM_replicateM但事实证明,重新定义它们大约比导入它们需要更少的空间。

我也放弃了前奏曲,转而只在之前和之后readParen打电话。lex在当前版本中,不需要验证右括号:在有效输入上,它会一直存在。另一方面,检查开头是至关重要的:因为数字只有在整个子表达式被读取后才会被转换,所以需要大量的回溯才能与正确的解析对齐。

在具有无限内存和空闲时间的理论机器上,该"("<-部分可能会被丢弃(增加 4 个字符,总共 308 个字符)。除非调用read只是中止。在我的身上,堆栈溢出得非常快。

于 2009-10-04T21:15:24.443 回答
2

m4 带 echo 和 bc,339 字节

这个解决方案是一个完整而彻底的 hack,它让我很头疼。除其他外,它包含转义的双引号、未转义的双引号、无法转义的反引号和单引号对(包括嵌套的七引号对)、未引用的正则表达式、将十进制乘法外包给 bc,以及使用 craZy 大小写来规避宏扩张。但我想它必须完成。:p

这为以前的解决方案(迭代循环、带 lambda 映射的递归、标签和分支、正则表达式和 eval 等)添加了“终极宏化”解决方案。

我认为一个很好的术语是“macroni code”:D

(为清楚起见,每 60 个字符换行一次)

define(T,`translit($@)')define(Q,`patsubst($@)')define(I,0)Q
(T(T(T(Q(Q(Q(Q(Q(Q(T(include(A),(),<>),>\s*>,>>),>\s*<,>;),\
([a-z]+\)\s*<,`*ifElsE<rEgExp<P;``````` \1 ''''''';0>;0;<'),
^<,`defiNe<````I';iNcr<I>>\\"Case `#'I:\\"defiNe<`A'''';'),^
[0-9]*),.+ [0-9]+.*,`dEfiNE<```P';`\& '''>A'),<>;N,`(),n'),E
,e),()),.*,`syscmd(`echo "\&"|bc -l')')

用法:$ cp input.in A; m4 thisfile.m4 > output.out

不过,我是一个 m4 n00b,在写这篇文章前一个小时就学会了。所以可能还有改进的余地。

于 2009-12-31T01:11:41.643 回答
1

方案(Guile 1.8)

这是我的版本,大小为 278 字节(KirarinSnow 对其进行了改进,将其降低到 273),去掉了所有换行符(当然,字符串文字中的换行符除外)。它仅适用于 Guile 1.8(因为在标准 Scheme 中,define它是一种语法,而不是一个对象,但 Guile 无论如何都将它表示为一个对象)。

(define ! define)
(!(c f p w . r)(if(null? r)(* p w)(apply c f(* p w)((if(memq(car r)f)cadr caddr)r))))
(!(d . l)(map display l))
(!(r . x)(read))
(! n(r))
(do((i 1(1+ i)))((> i n))(r)(let((t(r)))(d"Case #"i":
")(do((a(r)(1- a)))((= a 0))(r)(d(apply c(map r(iota(r)))1 t)"
"))))
于 2009-09-16T14:21:39.350 回答
1

698 字节的 C++
使用 'g++ -o test source.cpp -include iostream -include vector -include sstream' 编译

#define R(x,f,t) for(int x=f;x<t;x++){
#define S(x) x.size()
#define H string
#define U while
#define I if
#define D cin>>
#define X t.substr(p,S(t))
using namespace std;
int main(){int h,l,n,a,p,Y,W;D h;for(int q=1;q<=h;q++){D l;H s;char c;D c;R(i,0,l)H L;getline(cin,L);R(j,0,S(L))I (L[j]==41||L[j]==40)s+=32;s+=L[j];I(L[j]==40)s+=32;}}D a;printf("Case #%d:\n",q);R(i,0,a)H N;D N;D n;vector<H>f;R(j,0,n)D N;f.push_back(N);}H t=s;float P=1;p=0;U(p<S(t)-1){p=0;U(t[p]!=48&&t[p]!=49)p++;t=X;stringstream T(t);float V;T>>V;H F;T>>F;P*=V;I(F[0]==41)break;Y=0;R(j,0,S(f))if(F==f[j])Y=1;}p=t.find(40)+1;t=X;p=0;I(Y==0){W=1;U (W>0){I(t[p]==40)W++;I(t[p]==41)W--;p++;}t=X;p=0;}}cout<<P<<endl;}}return 0;}

编辑:对不起;我认为包含是可以的(例如,C 甚至可以在不包含基本库的情况下工作),而我确信如果我以这种方式取消定义的话。我现在不在家,也有一段时间不在家:我无法修改它。忽略我的提交。

于 2009-10-03T17:45:32.377 回答
1

718 字节的 OCaml

我是 OCaml n00b,所以这可能比它需要的要长得多。

用法:ocaml thisfile.ml <input.in >output.out

#load"str.cma";;open List;;open String;;open Str;;let x=length and
y=Printf.printf and e=global_replace and h=float_of_string and b=regexp and
k=index and r=read_line and a=read_int and w s m c=sub s(c+1)(m-c-1);;for i=1to
a()do y"Case #%d:\n"i;let t=let n=a()in let rec g d j=if j>n then d else
g(d^(r()))(j+1)in e(b" ")""(e(b"\\b")"^"(g""1))and n=a()in let rec z j=if j>n
then()else let q=tl(split(b" ")(r()))in let rec g l j s p=let o=k s '('and c=k
s ')'in if j then let f=w s c o in if contains f '('then let m=k s '^'in let
c=index_from s(m+1)'^'in g 0(mem(w s c m)q)(w s(x s)c)(h(w s m o)*.p)else h f*.p
else if o<c then g(l+1)j(w s(x s)o)p else g(l-1)(l=1)(w s(x s)c)p in y"%f\n"(g
0(0=0)t 1.);z(j+1)in z 1done
于 2009-10-09T23:12:23.620 回答
1

440字节的纯java

一个不使用任何 eval 技巧的较短的 java 解决方案。如果忽略 stderr 输出,可以通过删除 System.exit(0) 将其减少到 425。

import java.util.*;enum A{_;Scanner c,d;float p(String a){return
d.nextFloat()*(d.hasNext("\\D+")?a.contains(' '+d.next()+' ')?p(a)+0*p(a):0*p(a)+p(a):1);}{c=new
Scanner(System.in);for(int n=c.nextInt(),i=0,l;i++<n;){String
s="";for(l=c.nextInt();l-->=0;)s+=c.nextLine();System.out.println("Case #"+i+":");for(l=c.nextInt();l-->0;){c.next();d=new
Scanner(s.replaceAll("[()]"," "));System.out.println(p(c.nextLine()+' '));}}System.exit(0);}}
于 2009-10-21T17:43:40.880 回答
0

Haskell,514 字节(我很烂?)。

基于quibble 的解决方案

import Control.Monad
import Text.ParserCombinators.Parsec
data F=N|F String(Float,F)(Float,F)
r=return
f=many1 letter>>= \i->w>>d>>= \t->d>>=r.F i t
d=char '('>>w>>many1(oneOf".0123456789")>>= \g->w>>(f<|>r N)>>= \p->char ')'>>w>>r(read g,p)
w=many$oneOf" \n"
g=getLine
l=readLn
m=replicateM
main=l>>= \n->forM_[1..n]$ \t->putStrLn("Case #"++show t++":")>>l>>=(`m`g)>>=(\(Right q)->l>>=(`m`p q)).parse d"".join
z(p,f)=(p*).y f
y N _=1
y(F n t f)x=z(if n`elem`x then t else f)x
p q=fmap(drop 2.words)g>>=print.z q
于 2009-09-17T22:55:28.243 回答
0

C 489 字节

以 80 个字符包装的代码,实际上只有 3 行。

保存在 ac 中并编译: gcc -w ac -oa

#define S int I,N;scanf("%d\n",&N);for(I=-1;++I<N;)
#define M 1000
char B[M],Z[M],Q[M]={' '},*F[M],*V;float W[M],H;int J,C,L[M],R[M];t(){V=strtok(0
," \n()");}p(){int U=C++;F[U]=0;if(!V)t();sscanf(V,"%f",W+U);t();if(V&&*V>='a')s
trcpy(Q+1,V),V=0,F[U]=strdup(strcat(Q," ")),L[U]=p(),R[U]=p();return U;}main(){S
{printf("Case #%d:\n",I+1);*B=0;{S strcat(B,gets(Z));}V=strtok(B," \n(");C=0,p()
;{S{strcat(gets(B)," ");for(J=0,H=W[0];F[J];J=strstr(B,F[J])?L[J]:R[J],H*=W[J]);
printf("%f\n",H);};}}}
于 2009-09-27T03:23:32.900 回答
0

R 280 字节

注意:在 R 的标准发行版上(从 v. 2.9.2 开始),该程序不会传递大输入,并且仅在 Case 28(嵌套到 99 级)上失败,产生“上下文堆栈溢出”。src/main/gram.c要解决此问题,请修改其中的行

#define CONTEXTSTACK_SIZE 50

并将 50 替换为 500 之类的内容。然后重新编译。瞧!

n=0
g=gsub
eval(parse(text=g('[^
]* [0-9]+( [^
]*|
)','f=c(\\1)
cat(eval(d),"
")
',g('
\\(','
cat("Case #",n<-n+1,":
",sep="")
d=expression(',g('" "','","',g(')\\s*\\(',',',g(' *("[a-z]+")\\s*\\(','*ifelse(\\1%in%f,',g('([a-z]+)','"\\1"',paste(readLines('A'),collapse='
')))))))))

用法(需要重命名输入):cp input.in A; R -q --slave -f thisfile.R >output.out

于 2009-10-19T00:48:04.980 回答
0

F#:759 个重要字符(哇,我不擅长这个;))

最小化版本

open System.Text.RegularExpressions
type t=T of float*(string*t*t)option
let rec e=function x,T(w,Some(s,a,b))->e(x,if Set.contains s x then a else b)*w|x,T(w,_)->w
let rec h x=Regex.Matches(x, @"\(|\)|\d\.\d+|\S+")|>Seq.cast<Match>|>Seq.map (fun x -> x.Value)|> Seq.toList
let rec p=function ")"::y->p y|"("::w::x::y->match x with ")"->T(float w,None),y|n->let a,f=p y in let b,g=p f in T(float w,Some(n,a,b)),g
let solve input =
    Regex.Matches(input,@"(\(((?<s>\()|[^()]|(?<-s>\)))*\)(?(s)(?!)))\s+\d+\s+((\S+\s\d(.+)?\s*)+)")
    |>Seq.cast<Match>
    |>Seq.map(fun m->fst(p(h(m.Groups.[1].Value))), [for a in m.Groups.[3].Value.Trim().Split([|'\n'|])->set(a.Split([|' '|]))])
    |>Seq.iteri(fun i (r,c)->printfn"Case #%i"(i+1);c|>Seq.iter(fun x->printfn"%.7F"(e(x, r))))

可读版本

open System.Text.RegularExpressions

type decisionTree = T of float * (string * decisionTree * decisionTree) option
let rec eval = function 
    | x, T(w, Some(s, a, b)) -> eval(x, if Set.contains s x then a else b) * w
    | x, T(w, _) -> w

// creates a token stream
let rec tokenize tree =
    Regex.Matches(tree, @"\(|\)|\d\.\d+|\S+")
    |> Seq.cast<Match>
    |> Seq.map (fun x -> x.Value)
    |> Seq.toList

// converts token stream into a decisionTree
let rec parse = function
    | ")"::xs -> parse xs
    | "("::weight::x::xs ->
        match x with
        | ")" -> T(float weight, None), xs
        | name ->
            let t1, xs' = parse xs
            let t2, xs'' = parse xs'
            T(float weight, Some(name, t1, t2)), xs''

// uses regex to transform input file into a Seq<decisionTree, list<set<string>>, which each item in our 
// list will be tested against the decisionTree
let solve input =
    Regex.Matches(input, @"(\(((?<s>\()|[^()]|(?<-s>\)))*\)(?(s)(?!)))\s+\d+\s+((\S+\s\d(.+)?\s*)+)")
    |> Seq.cast<Match>
    |> Seq.map (fun m -> fst(parse(tokenize(m.Groups.[1].Value))), [for a in m.Groups.[3].Value.Trim().Split([|'\n'|]) -> set(a.Split([|' '|])) ])
    |> Seq.iteri (fun i (tree, testCases) ->
            printfn "Case #%i" (i+1)
            testCases |> Seq.iter (fun testCase -> printfn "%.7F" (eval (testCase, tree)))
        )
于 2009-12-25T23:16:16.363 回答