Language agnostic 文件修复代码高尔夫(GCJ 2010 1B-A)

Language agnostic 文件修复代码高尔夫(GCJ 2010 1B-A),language-agnostic,rosetta-stone,Language Agnostic,Rosetta Stone,去年(2009年),第1B轮的第一个问题是一个有趣的问题: 由于这个问题似乎是为类似Lisp的语言量身定做的,因此我们自然而然地就有了这样一个问题,即一些语言使用了许多不同的技术,以比任何Lisp语言都少的字符解决了这个问题 今年的第1B轮问题A()似乎也是为一个特定的语言家族,unixshell脚本量身定做的。因此,继续“1B-A传统”是合适的:但是哪种语言的代码最短?让我们来看看吧 问题描述(改编自官方网页): 您将获得T测试用例。每个测试用例都包含N行,其中列出了计算机上当前存在的所有目录

去年(2009年),第1B轮的第一个问题是一个有趣的问题:

由于这个问题似乎是为类似Lisp的语言量身定做的,因此我们自然而然地就有了这样一个问题,即一些语言使用了许多不同的技术,以比任何Lisp语言都少的字符解决了这个问题

今年的第1B轮问题A()似乎也是为一个特定的语言家族,unixshell脚本量身定做的。因此,继续“1B-A传统”是合适的:但是哪种语言的代码最短?让我们来看看吧

问题描述(改编自官方网页):

您将获得T测试用例。每个测试用例都包含N行,其中列出了计算机上当前存在的所有目录的完整路径。例如:

/home
/home/awesome
/home/awesome/wheeeeeee
/home/awesome/wheeeeeee/codegolfrocks
/home/thecakeisalie
接下来,将为您提供M行,列出您要创建的目录的完整路径。它们的格式与前面的示例相同。您可以使用
mkdir
命令创建目录,但只有在父目录已经存在时才能这样做。例如,要创建目录
/pyonpyon/fumufumu/yeahyeaheah
/pyonpyon/fumufumu/yeahyeaheah
,您需要使用
mkdir
四次:

mkdir /pyonpyon
mkdir /pyonpyon/fumufumu
mkdir /pyonpyon/fumufumu/yeahyeah
mkdir /pyonpyon/fumufumu/yeahyeahyeah
对于每个测试用例,返回必须调用
mkdir
来创建所有要创建的目录的次数

输入

输入由一个文本文件组成,其第一行包含整数T,即测试用例数。文件的其余部分包含测试用例

每个测试用例从一行开始,该行包含整数NM,用空格分隔

接下来的N行包含计算机上当前存在的每个目录的路径(不包括根目录
/
)。这是一个或多个非空小写字母数字字符串的串联,每个字符串前面都有一个
/

以下M行包含要创建的每个目录的路径

输出

对于每个案例,打印一行包含
case#X:Y
,其中
X
是案例编号,
Y
是解决方案

限制

1[([){exch}/C{concatstrings}/R{(%lineedit)run}>>begin 1
R{(: )[(Case #)3{=only}repeat<<>>R 1 index add{()<<R]{99 string
cvs C<C>C dup 3 index[<>put}forall pop}repeat[length[sub =}for
1({[([){exch}/R{(%lineedit)run}>>begin R{(: )[(Case #)3{=only}repeat<<>>R 1
index +{<><<R]{str cat<C>cat dup 3 index[<>put}forall pop}repeat[length[-
=}for}1)
一,≤ T≤ 一百

0≤ N≤ 一百

一,≤ M≤ 一百

每个路径最多包含100个字符

每个路径在计算机上已存在的目录列表或所需目录列表中仅显示一次。但是,路径可能出现在两个列表中,如下面的示例3所示

如果某个目录位于计算机上已存在的目录列表中,则其父目录也将列出,但根目录除外
/

输入文件的长度最多为100000字节

示例

可以下载更大的样本测试用例

输入:

3
0 2
/home/sparkle/pyon
/home/sparkle/cakes
1 3
/z
/z/y
/z/x
/y/y
2 1
/moo
/moo/wheeeee
/moo
输出:

Case #1: 4
Case #2: 4
Case #3: 0
编码高尔夫

请用解决此问题的任何语言发布最短代码。输入和输出可以通过stdin和stdout或您选择的其他文件进行处理如果您的代码在执行时可能修改或删除现有文件,请附上免责声明。

获胜者将是在2010年第1B轮开始前已经实现的语言中的最短解决方案(按字节计数)。因此,虽然您可以自由地使用刚刚编写的语言来提交0字节的解决方案,但这并不重要,您可能会获得否决票^_^

排名

1[([){exch}/C{concatstrings}/R{(%lineedit)run}>>begin 1
R{(: )[(Case #)3{=only}repeat<<>>R 1 index add{()<<R]{99 string
cvs C<C>C dup 3 index[<>put}forall pop}repeat[length[sub =}for
1({[([){exch}/R{(%lineedit)run}>>begin R{(: )[(Case #)3{=only}repeat<<>>R 1
index +{<><<R]{str cat<C>cat dup 3 index[<>put}forall pop}repeat[length[-
=}for}1)
  • 六十五
  • 一百
  • 121(不包括翻译选项)
  • 128
  • 144
  • 145
  • 158
  • 159
  • 172
  • 182
  • 189
  • 218
  • 284
  • 398
Bash,175 169 168 135 130 128 警告:确保在空目录中运行,因为这将在每次测试中首先清除其内容

read t
for((;x++<t;));do
rm -r *
read n m
for((i=n+m;i--;));do
read d
mkdir -p .$d
done
echo Case \#$x: $[`find|wc -l`-n-1]
done
readt
对于(;x++Golfscript,74 69 65
现在在一行上!
这个解决方案是63个字符,但是对于具有数千条路径的测试用例(超过8分钟),它不会在合理的时间内运行,所以我选择不计算它

n%(~,{'Case #'\)@': '\(~1$+@[]@{\('/':!%@\{[n!++:!]|}/}*,@-n@}/
更快的65字符解决方案:

n%(~,{'Case #'\)@': '\(~1$+@[]@{\('/':!%@\{[n!++:!]+}/.&}*,@-n@}/
感谢marcog的算法!

Python,193 175 173 171 166 165 164 156 151 149 147 146 145 这个解决方案抛出了一个EOFError,但是因为它是输出到stderr的,所以它在规则范围内。因为我们感兴趣的输出都是到stdout的,所以我们可以通过管道忽略stderr

你可能读了上面的文章(或其他一些文章),认为它不应该起作用。原因有点小技巧,我将在这里解释。如果你仔细阅读这个问题,它告诉我们,对于第一个列表中的每个目录,它的所有父目录也都包含在列表中(例如,如果/home/marcog存在,那么/home也存在)[1].该问题还向我们保证,每份清单不会有重复[2]。这使我们可以将第一个列表中的所有目录放入第二个列表中的目录所在的集合中。由于问题保证每个列表没有重复项,我们知道第一个列表将在集合中产生正好N个条目。因此,我们可以通过从最终集合的大小中减去N来获得最终答案

[1] “接下来的N行分别给出计算机上已存在的一个目录的路径。此列表将包括除根目录之外的计算机上已存在的所有目录。”

[2] “在您计算机上已存在的目录列表中,或在您希望创建的目录列表中,没有路径会出现两次。”

C#,489 442 400 398 只是为了好玩,当然不可能做得很短。伯爵是在搬进来之后
r,n=io.read,"*n"for i=1,r(n)do a,c,s=r(n),0,{}for i=1,a+r()do k=""for x in r():gmatch"[^/]+"do k=k.."/"..x c=c+(s[k]or 1);s[k]=0 end end print("Case #"..i..": "..(c-a))end
import Data.List
import Text.Printf
a[]=[]
a(x:z)=(r-n):next where{;[n,m]=map read$words x;t=n+m;r=length$nub$concatMap(f.reverse)$take t z;next=a$drop t z;f""=[];f y=y:f z where(a,b:z)=span(/='/')y}
main=do{z<-getContents;putStr$unlines[printf"Case #%d: %d"x v|(x::Int,v)<-zip[1..]$a$tail$lines z]}
import Data.List
import Text.Printf

a [] = []
a (x:xs) = (r-n) : next where
    [n,m] = map read $ words x
    t = n+m
    r = length $ nub $ concatMap (f . reverse) $ take t xs
    next = a $ drop t xs
    f "" = []
    f y = y : f bs where
        (a,b:bs) = span (/= '/') y

cleanUp a = unlines [printf "Case #%d: %d" x v | (x::Int,v::Int) <- zip [1..] a]

main = do
    z<-getContents
    putStr$cleanUp$a$tail$lines z
gets.to_i.times{|i|n,m=gets.split.map &:to_i
d={}
(n+m).times{gets.strip.split('/').inject{|a,p|d[a+='/'+p]=a}}
puts"Case ##{i+1}: #{d.size-n}"}
1({[([){exch}/R{(%lineedit)run}>>begin R{(: )[(Case #)3{=only}repeat<<>>R 1
index +{<><<R]{str cat<C>cat dup 3 index[<>put}forall pop}repeat[length[-
=}for}1)
import Data.List
main=interact$(!1).tail.lines
(l:j)!i=let{[n,m]=map read$words l;(p,k)=splitAt(n+m)j}in"Case #"++show i++": "++show(length(nub$(>>=s)p)-n)++"\n"++k!(i+1)
s(_:p)=map(flip take p)$elemIndices '/'(p++"/")
import Data.List
main = interact $ testsStartingAt 1 . tail . lines
testsStartingAt _   []   = "" -- this line optional
testsStartingAt i (l:ls) = testOutput ++ testsStartingAt (i+1) ls'
    where [n,m]       = map read $ words l
          (paths,ls') = splitAt (n+m) ls
          testResult  = length (nub $ concatMap splitPath paths) - n
          testOutput  = "Case #" ++ show i ++ ": " ++ show testResult ++ "\n"
splitPath (_:p) = map (flip take p) $ elemIndices '/' (p ++ "/")
perl -naE 'BEGIN{<>}++$i;($n,$m,%d)=@F;for(1..$n+$m){$_=<>;$d{$`}++while/\w\K\b/g}say"Case #$i: ",keys(%d)-$n'
#! perl -na      # activate line mode and autosplit
BEGIN { <> }     # skip test case count

# now for each test case:

++$i;            # increment test counter
($n,$m,%d) = @F; # read N and M;
                 # clear out directory hash

for (1..$n+$m) { # for each expected pathname:
  $_ = <>;          # read it
  $d{$`}++          # add to hash...
    while /\w\K\b/g # ...all branches from root
}

say "Case #$i: ", keys(%d) - $n
for$i(1..<>){($n,$m,%d)=split$",<>;
for(1..$n+$m){$_=<>;$d{$`}++while/\w\K\b/g}
say"Case #$i: ",keys(%d)-$n}
function p(){if(c++>1)print"Case #"c-2": "length(k)-n}
/\//{for(y=i=1;i<NF;)k[y=y"/"$++i];next}
{p();n=$1;delete k}
END{p()}
BEGIN{FS=" |/"}
for(c←1 to readInt){val I=readLine split" "map(_.toInt)
var d=Set("")
for(i←1-I(0)to I(1)){var a="";for(w←readLine split"/"){a+="/"+w;d+=a}}
printf("Case #%d: %d\n",c,d.size-I(0)-2)}
c=:0
f=:3 :0
c=:>:c
'a b'=:({.,+/)".>{.y
('Case #',(":c),': ',":a-~3 :'#~.,/>\"1<;.1"1 y'>(>:i.b){y)1!:2<2
(>:b)}.y
)
f^:_(}.<;._2 (1!:1)<3)
script.ijs < gcj-input