说我有这样的文本(每个单词一行,没有空格)
Programming
Puzzles
&
Code
Golf
这是没有意义的!它完全违背了物理定律。
您的挑战是要纠正这种不可能的情况并像这样折叠文本:
P
Prog
&uzz
Coderam
Golflesming
因此,在任何字符下方都没有空白,但是字符保持了垂直顺序。
目的是满足要求,但使用尽可能少的源代码字节。
说我有这样的文本(每个单词一行,没有空格)
Programming
Puzzles
&
Code
Golf
这是没有意义的!它完全违背了物理定律。
您的挑战是要纠正这种不可能的情况并像这样折叠文本:
P
Prog
&uzz
Coderam
Golflesming
因此,在任何字符下方都没有空白,但是字符保持了垂直顺序。
目的是满足要求,但使用尽可能少的源代码字节。
Answers:
jb_.T.T_.z
在Pyth编译器/执行器上在线尝试。
我们可以通过应用四个简单的转换来获得所需的输出:
颠倒顺序:
Golf
Code
&
Puzzles
Programming
转置行和列:
GC&PP
oour
ldzo
fezg
lr
ea
sm
m
i
n
g
此顶部对齐,折叠了原始列。
转置行和列:
Golflesming
Coderam
&uzz
Prog
P
颠倒顺序:
P
Prog
&uzz
Coderam
Golflesming
.z Read the input as a list of strings, delimited by linefeeds.
_ Reverse the list.
.T.T Transpose the list twice.
_ Reverse the list.
jb Join its strings; separate with linefeeds.
import Data.List
p=reverse;o=transpose
f=unlines.p.o.o.p.lines
我很成熟
l=[]
for x in input().split('\n'):n=len(x);l=[a[:n]+b[n:]for a,b in zip(l+[x],['']+l)]
print'\n'.join(l)
迭代的一遍算法。我们按顺序浏览每一行,更新行列表l
以输出。新单词有效地从底部推出,将其上方的所有字母都移了一个空格。例如,在测试用例中
Programming
Puzzles
&
Code
Golf
完成后Code
,我们有
P
Prog
&uzzram
Codelesming
然后将Golf
结果添加到
P
Prog
&uzz
Coderam
Golflesming
我们可以将其视为两个部分的组合
P |
Prog |
&uzz |
Code | ram
Golf | lesming
第一乐章上移了golf
。我们使用zip
使用元素末尾(左侧)的输出列表的a在输出列表中以空行(右侧)的优先级并在新元素的长度处截去每个部分。
相反地,向后迭代似乎更自然,让新字母从顶部掉下来,但我尝试这样做的时间更长。
为了进行比较,这是一个zip
/ filter
方法,map(None,*x)
用于iziplongest
(109字节):
f=lambda z:[''.join(filter(None,x))for x in map(None,*z)]
lambda x:'\n'.join(f(f(x.split('\n')[::-1]))[::-1])
(模板字符串中的2个换行符很重要并已计数)
@Dennis的想法在JavaScript中实现。冗长的S函数逐行进行转置,逐字符进行转置,将结果保留在t
数组中。
a=>(S=z=>{for(t=[];z.join``;t.push(w))for(w='',n=z.length;n--;z[n]=z[n].slice(1))w+=z[n][0]||''},S(a.split`
`),S(t.reverse()),t.reverse().join`
`)
片段内打高尔夫球的次数减少(在Firefox中尝试)
F=a=>(
S=z=>{
for(t=[];z.join``;t.push(w))
for(w='',n=z.length;n--;z[n]=z[n].slice(1))
w+=z[n][0]||''
},
S(a.split`\n`),
S(t.reverse()),
t.reverse().join`\n`
)
#I,#O { margin:0; width: 200px; height:100px; border: 1px solid #ccc }
<table><tr><td>
Input<br><textarea id=I>Programming
Puzzles
&
Code
Golf
</textarea></td><td>
Output<pre id=O></pre>
</td></tr></table>
<button onclick='O.innerHTML=F(I.value)'>go</button>
S(t.reverse()),t.reverse().join
为减少几个字节S(R=t.reverse()),R.join
。
function(x){a=apply(do.call(rbind,lapply(p<-strsplit(strsplit(x,"\n")[[1]],""),function(x)c(x,rep(" ",max(lengths(p))-length(x))))),2,function(x)c(x[x==" "],x[x!=" "]));for(i in 1:nrow(a))cat(a[i,][a[i,]!=" "],"\n",sep="")}
这是一种荒谬而漫长的天真方法。
取消高尔夫:
f <- function(x) {
# Start by spliting the input into a vector on newlines
s <- strsplit(x, "\n")[[1]]
# Create a list consisting of each element of the vector
# split into a vector of single characters
p <- strsplit(s, "")
# Pad each vector in p to the same length with spaces
p <- lapply(p, function(x) c(x, rep(" ", max(lengths(p)) - length(x))))
# Now that the list has nice dimensions, turn it into a matrix
d <- do.call(rbind, p)
# Move the spaces to the top in each column of d
a <- apply(d, 2, function(x) c(x[x == " "], x[x != " "]))
# Print each row, omitting trailing whitespace
for (i in 1:nrow(a)) {
cat(a[i, ][a[i, ] != " "], "\n", sep = "")
}
}
您可以 在线尝试。
function f(s)
c=char(strsplit(s,[10 '']));[~,i]=sort(c>32);[m,n]=size(c);c(i+repmat((0:n-1)*m,m,1))
范例:
在变量中定义输入字符串,例如s
。10
是换行符:
>> s = ['Programming' 10 'Puzzles' 10 '&' 10 'Code' 10 'Golf'];
f
带输入的调用函数s
:
>> f(s)
ans =
P
Prog
&uzz
Coderam
Golflesming
F=s=>(C=o=>--a.length?C(a.reduce((p,c,i)=>c+p.slice((a[i-1]=p.slice(0,c.length)).length)))+`
`+o:o)(a=(s+`
`).split`
`)
在这里,它是没有意义的,在ES5中带有解释其工作原理的注释:
function F(s) {
var arr = (s+'\n').split('\n'); // Create an array of words and append an empty member
return (function C(output) {
return --arr.length ? // Remove the last item from the array
C(arr.reduce(function(p,c,i) { // If the array still has length reduce it to a string and recurse
var intersection = (arr[i-1] = p.slice(0, c.length)) // Overwrite the previous word with the part that intersects the current word
return c + p.slice(intersection.length) // Add the part of the previous word that doesn't intersect to the current value
})) + '\n' + output : output // Add the last level of recursions output on to the end of this
})(arr);
}
input.addEventListener('input', updateOutput, false);
function updateOutput() {
var oldLength = input.value.length;
var start = this.selectionStart;
var end = this.selectionEnd;
input.value = input.value.split(/ +/).join('\n');
var newLength = input.value.length;
input.setSelectionRange(start, end + (newLength - oldLength));
output.value = F(input.value).trim();
}
updateOutput();
textarea {
width: 50%;
box-sizing: border-box;
resize: none;
float: left;
height: 10em;
}
label {
width: 50%;
float: left;
}
<p>Type in the input box below, spaces are automatically converted to newlines and the output updates as you type</p>
<label for="input">Input</label>
<label for="output">Output</label>
<textarea id="input">
Type inside me :)
</textarea>
<textarea id="output" disabled>
</textarea>
大概还有一些打高尔夫球的空间。那里可能有一些不必要的操作
l=lapply;s=substring;C=rbind;d=do.call;cat(C(d(C,l(apply(d(C,l(a<-scan(,''),s,1:(w=max(nchar(a))),1:w))[(h=length(a)):1,],2,paste0,collapse=''),s,1:h,1:h))[,h:1],'\n'),sep='')
脱节和解释
a<-scan(,'') # get STDIN
h<-length(a) # number of lines
w=max(nchar(a)) # length of longest line
M<-lapply(a,substring,1:w,1:w) # create a list of split strings with empty chars
M<-do.call(rbind,M)[h:1,] # turn it into a matrix with line order reversed
M<-apply(M,1,paste0,collapse='') # paste together the columns
M<-lapply(M,substring,1:h,1:h) # split them back up
M<-do.call(rbind,M)[,h:1] # reform a matrix
M<-rbind(M,'\n') # add some carriage returns
cat(M,sep='') # output with seperators
测试运行。有趣的是,由于扫描的工作方式,整个句子可以用空格输入,但仍按指定给出输出。
> l=lapply;s=substring;C=rbind;d=do.call;cat(C(d(C,l(apply(d(C,l(a<-scan(,''),s,1:(w=max(nchar(a))),1:w))[(h=length(a)):1,],2,paste0,collapse=''),s,1:h,1:h))[,h:1],'\n'),sep='')
1: Programming
2: Puzzles
3: &
4: Code
5: Golf
6:
Read 5 items
P
Prog
&uzz
Coderam
Golflesming
> l=lapply;s=substring;C=rbind;d=do.call;cat(C(d(C,l(apply(d(C,l(a<-scan(,''),s,1:(w=max(nchar(a))),1:w))[(h=length(a)):1,],2,paste0,collapse=''),s,1:h,1:h))[,h:1],'\n'),sep='')
1: Programming Puzzles & Code Golf beta
7:
Read 6 items
P
Prog
&uzz
Code
Golfram
betalesming
>
在名为ab的文件中输入内容,现在最多可使用24个字符。稍后将更新以使其与更多产品一起使用。另外,在在线编译器中也不起作用。需要非自由编译器。
gl l=24/
forv x=1/$l{
gl a="$a str a`x' `x'"
}
infix $a using a.b
gl b=_N
forv k=1/$l{
gen b`k'=0
qui forv i=$b(-1)1{
forv j=`i'/$b{
replace b`k'=1 if _n==`j'&a`k'==""
replace a`k'=a`k'[_n-1] if _n==`j'&a`k'==""
replace a`k'="" if _n==`j'-1&b`k'[_n+1]==1
replace b`k'=0
}
}
}
forv i=1/$b{
forv k=1/$l{
di a`k'[`i'] _c
}
di
}
编辑:从循环中的每个语句安静地(抑制输出)移动到循环本身,节省8个字节。
S=scan(,"");while(any((D<-diff(N<-sapply(S,nchar)))<0)){n=max(which(D<0));S[n+1]=paste0(S[n+1],substr(S[n],N[n]+D[n]+1,N[n]));S[n]=substr(S[n],1,N[n]+D[n])};cat(S,sep="\n")
带有换行符和缩进:
S=scan(,"") #Takes input from stdin
while(any((D<-diff(N<-sapply(S,nchar)))<0)){
n=max(which(D<0))
S[n+1]=paste0(S[n+1],substr(S[n],N[n]+D[n]+1,N[n]))
S[n]=substr(S[n],1,N[n]+D[n])
}
cat(S,sep="\n")
用法:
> S=scan(,"");while(any((D<-diff(N<-sapply(S,nchar)))<0)){n=max(which(D<0));S[n+1]=paste0(S[n+1],substr(S[n],N[n]+D[n]+1,N[n]));S[n]=substr(S[n],1,N[n]+D[n])};cat(S,sep="\n")
1: Programming
2: Puzzles
3: &
4: Code
5: Golf
6:
Read 5 items
P
Prog
&uzz
Coderam
Golflesming
可以肯定的是,我可以更改保存字节的方法,但是稍后。
:p非高尔夫esolang击败常规lang:p
Turtlèd的奇怪之处在于它最初是在讨论ascii艺术语言后才制成的,但实际上似乎最能应对此类挑战
Turtlèd不能接受换行符输入,而只能接受多个输入,并且仅接受一个输入:用空格(包括最后一个)终止每个单词。
!l[*,+r_][ l]ur[*,[ -.]+.[ r{ d}u+.]-.[ -.]{ l}[ l]r[ u]_]' d[ d]u[ ' r]
! Take string input
l Move left, off the asterisk at the start of grid
[* ] Until cell is *
,+r_ write *, string pointer+=1, move right, write * if pointed char is last char
[ l]ur move left until finding a space, move up and right
[* ] Until cell is *
, write *
[ ] until cell is [space]
-. decrement string pointer, write pointed char
+. increment and write string pointer
[ ] until cell is [space]
r{ d} move right, move down until finding nonspace
u+. move up, string pointer+=1 and write pointed char
-. decrement string pointer and write pointed char
[ ] until cell is [space]
-. string pointer-=1 and write pointed char
{ l} move left until finding nonspace
[ l] move left until finding space
r move right
[ u] move up until finding space
_ write * if pointed char is last char
(if it is written, loop ends)
' d[ d]u[ ' r] just cleanup
这是我面临的挑战之一,这些挑战从过分艰辛,变得容易,变得比我预期的要多得多……我对这种方法不是特别满意,我敢肯定有一种挑战更好的方法来减少 print pop@F...
使用-n
或仅使用正则表达式的,但我现在无法到达...最初我在使用say
,但是我认为我必须得得分更高(use 5.01
)$'
。
@F=(/.+/g,@F)for<>;$_%=$#F,($x=length$F[$_++])<length$F[$_]&&($F[$_]=~/.{$x}/,$F[$_-1].=$',$F[$_]=$&)for 0..1e2;print pop@F,$/while@F
另存为vertically-collapse-text.pl
。
perl vertically-collapse-text.pl <<< 'Programming
Puzzles
&
Code
Golf'
P
Prog
&uzz
Coderam
Golflesming
到达那里...
f=->a,i=-1{a.map{|l|i+=1;(0...l.size).map{|c|a.map{|x|x[c]}.join[~i]}*''}.reverse}
尝试的解释:
f=->a,i=-1{a.map{|l|i+=1; # For each line `l` with index `i` in string array `a`
(0...l.size).map{|c| # For each column `c` in `l`
a.map{|x|x[c]}.join # Make a string of non-nil characters `c` across `a`...
[~i] # ...and grap the `i`th character *from the end*, if any
}*''}.reverse} # Join the characters grabbed from each column and reverse the result
像这样运行它:
a = %w[
Programming
Puzzles
&
Code
Golf
]
puts f[a]
{+{(-#x)$x@&~^x}'+x@\:!|/#:'x}
。
k){+{(-#x)$x@&~^x}'+x@\:!|/#:'x}("Programming";"Puzzles";,"&";"Code";"Golf")
"P "
"Prog "
"&uzz "
"Coderam "
"Golflesming"
说明
x@\:!|/#:'x
扩展每个字符串以创建一个方形字符矩阵。
k){x@\:!|/#:'x}("Programming";"Puzzles";,"&";"Code";"Golf")
"Programming"
"Puzzles "
"& "
"Code "
"Golf "
+
转置它
k){+x@\:!|/#:'x}("Programming";"Puzzles";,"&";"Code";"Golf")
"PP&CG"
"ru oo"
"oz dl"
"gz ef"
"rl "
"ae "
"ms "
"m "
"i "
"n "
"g "
{(-#x)$x@&~^x}
将删除字符串中的所有空格,然后以其原始长度填充字符串
k){(-#x)$x@&~^x}"a b c de f"
" abcdef"
将该函数应用于每个转置的字符串,然后翻转输出以获取结果
k){+{(-#x)$x@&~^x}'+x@\:!|/#:'x}("Programming";"Puzzles";,"&";"Code";"Golf")
"P "
"Prog "
"&uzz "
"Coderam "
"Golflesming"
{+{(-#x)$x@&~^x}'+(|/#:'x)$x}
为
^w[B!0]{w[B=32]{vb[1]^b[0]}>}b[1]vb[1]>b[2]<[X]w[B!2]{t[T+B]b[0]>}b[0]v[T]w[X!-1]{b[1]<}b[1]vb[1]w[B!0]{w[B!0]{^w[B!0]{>}<<<<^[Y+1]w[B!0]{<}>t[B]b[0]w[B!1]{v}v<[X]w[B!0]{>}b[T]}b[0]vb[1]^w[X!0]{<vb[1]^t[B]b[0]^w[B!0]{^}b[T]w[B!0]{v}}vw[B!0]{^^w[B!0]{>}<b[0]vvw[B=0]{<}b[0]<[X]}^^>w[B=0]{vb[1]}v<<}>>^b[0]^<b[0]
这悲剧。我几乎不记得它是如何工作的。
由于pb的输入工作方式(一次只一行),因此必须在输入中使用空格而不是换行符。如果解释器不是垃圾程序,并且您可以在输入中包含换行符,则唯一的更改是[B=32]
开始时变为[B=10]
。
我正在开发pbi(解释器)的更新,如果您想观看程序运行,它将清理视觉效果。它仍然需要大量工作,但与此同时,您可以在YouTube上观看此程序。
-.&' '"1&.(|:@|.)
非常愉快的解决方案。
说明:
-.&' '"1&.(|:@|.) input: list of strings y
|. reverse lines
|:@ then transpose
-.&' '"1 remove blanks from columns
&. and undo the inside
|:@|. (that is, transpose and reverse again.)
s
Programming
Puzzles
&
Code
Golf
|.s
Golf
Code
&
Puzzles
Programming
|:|.s
GC&PP
oo ur
ld zo
fe zg
lr
ea
sm
m
i
n
g
-.&' '"1|:|.s
GC&PP
oour
ldzo
fezg
lr
ea
sm
m
i
n
g
|.-.&' '"1|:|.s
g
n
i
m
sm
ea
lr
fezg
ldzo
oour
GC&PP
|.|:-.&' '"1|:|.s
P
Prog
&uzz
Coderam
Golflesming
(-.&' '"1)&.(|:@|.)s
P
Prog
&uzz
Coderam
Golflesming
-.&' '"1&.(|:@|.)s
P
Prog
&uzz
Coderam
Golflesming
f =: -.&' '"1&.(|:@|.)
f
-.&' '"1&.(|:@|.)
f >'Programming';'Puzzles';'&';'Code';'Golf'
P
Prog
&uzz
Coderam
Golflesming
g =: [: > [: <;._1 '|'&,
g 'Programming|Puzzles|&|Code|Golf'
Programming
Puzzles
&
Code
Golf
f g 'Programming|Puzzles|&|Code|Golf'
P
Prog
&uzz
Coderam
Golflesming
F =: f @ g
F &. > 'Programming|Puzzles|&|Code|Golf' ; '1|23|456|7890' ; '1234|567|89|0'
+-----------+----+----+
|P |1 |1 |
|Prog |23 |52 |
|&uzz |456 |863 |
|Coderam |7890|0974|
|Golflesming| | |
+-----------+----+----+
;@;:&.(|:@|.)
13
这使用了Dennis的Jelly答案中描述的算法。输入和输出都是字符串列表。不幸的是,如果内部列表或字符串的长度不一样,则内置的转置功能将无法很好地工作,这首先会破坏垂直折叠的点。欢迎打高尔夫球。在线尝试!
R2`;i(lZ♂Σ`nR
开球
Implicit input s.
R Reverse s.
2`...`n Run the following function twice.
;i Duplicate and flatten onto the stack.
(l Get the number of strings in the list.
Z Zip len strings together, which results in a list of lists of characters.
♂Σ Sum each list of characters, which essentially joins them together.
This function essentially transposes
R Reverse the result.
Implicit return.
(let((lr list-ref)(ls list-set)(sl string-length)(ss substring)(l(string-split s)))(let p((ch #f))
(for((i(-(length l)1)))(define s(lr l i))(define r(lr l(+ 1 i)))(define n(sl s))(define m(sl r))
(when(> n m)(set! l(ls l i(ss s 0 m)))(set! l(ls l(+ 1 i)(string-append r(ss s m n))))(set! ch #t)))(if ch(p #f)l)))
取消高尔夫:
(define (f s)
(let ((lr list-ref)
(ls list-set)
(sl string-length)
(ss substring)
(l (string-split s)))
(let loop ((changed #f))
(for ((i (sub1 (length l))))
(define s (lr l i))
(define r (lr l (add1 i)))
(define n (sl s))
(define m (sl r))
(when (> n m)
(set! l (ls l i (ss s 0 m)))
(set! l (ls l (add1 i)(string-append r (ss s m n))))
(set! changed #t)))
(if changed (loop #f)
l))))
测试:
(f "Programming Puzzles & Code Golf")
输出:
'("P" "Prog" "&uzz" "Coderam" "Golflesming")
v=>(v=v.split`
`).map(_=>v=v.map((x,i)=>v[++i]?x.slice(0,n=v[i].length,v[i]+=x.slice(n)):x))&&v.join`
`
在CR上拆分,外部地图可确保我们循环足够的时间,以允许“重力”将字母放到需要放下的程度。
内部映射首先检查是否有下一行,如果有,则较短,将溢出的内容放到下一行。例如,如果第一行具有“ ABCD”,第二行具有“ FG”,则将“ CD”从第一行放到第二行,以使第一行变为“ AB”,第二行变为“ FGCD”。
由于我们会尽可能多地执行这些操作,因此字母会尽可能地下降,从而使我们获得理想的结果。
¶¡RζðмζR»
或使用其他开始:
.BRøðмζR»
与@ Dennis♦的Pyth答案相似的方法。
-1个字节,感谢@Emigna替换ðõ:
为ðм
。
说明:
¶¡ # Split on new-lines
R # Reverse the list
ζ # Zip/Transpose with unequal-length items (with space filler by default)
ðм # Remove all spaces
ζ # Zip/Transpose unequal-length items (with space filler) again
R # Reverse the list again
» # Join the list by newlines, and output implicitly
替代说明:
.B # Box (implicitly splits on new-lines and appends spaces)
ø # Zip/Transpose with equal-length items
# Rest is the same
function(x)apply(x,2,function(.).[order(!is.na(.))])
#old,longer version did the same but less efficiently
#function(x)apply(x,2,function(x){n<-na.omit(x);c(rep("",length(x)-length(n)),n)}))
我在解释问题时有些自由,并假定文本以矩阵形式表示,每个单元格一个字符,因此:
x <- as.matrix(read.fwf(textConnection("Programming
Puzzles
&
Code
Golf"), widths=rep(1, 11)))
所以x变成:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
[1,] "P" "r" "o" "g" "r" "a" "m" "m" "i" "n" "g"
[2,] "P" "u" "z" "z" "l" "e" "s" NA NA NA NA
[3,] "&" NA NA NA NA NA NA NA NA NA NA
[4,] "C" "o" "d" "e" NA NA NA NA NA NA NA
[5,] "G" "o" "l" "f" NA NA NA NA NA NA NA
现在,我使用order
和[
对列进行排序,以使NA首先出现,然后是所有其他值:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
[1,] "P" NA NA NA NA NA NA NA NA NA NA
[2,] "P" "r" "o" "g" NA NA NA NA NA NA NA
[3,] "&" "u" "z" "z" NA NA NA NA NA NA NA
[4,] "C" "o" "d" "e" "r" "a" "m" NA NA NA NA
[5,] "G" "o" "l" "f" "l" "e" "s" "m" "i" "n" "g"
如果要求输出是单词,则会变得更长:
s <- (function(x)apply(x,2,function(.).[order(!is.na(.))]))(x)
s[is.na(s)]<-""
apply(s, 1, paste, collapse="")
# [1] "P" "Prog" "&uzz" "Coderam" "Golflesming"
function(x)
需要包含在字节数中。
function(x){l=nchar;o=function(y)which(diff(l(y))<0)[1];d=function(x,i)"[<-"(x,i:(j<-i+1),c(a<-substr(x[i],1,l(x[j])),sub(a,x[j],x[i])));while(!is.na(o(x)))x=d(x,o(x));x}
可读版本:
f<-function(x){
l=nchar;
# find the first line in x that is longer than the next line
# if no such line exists o(x) will be NA
o = function(y) which(diff(l(y))<0)[1]
# d(x,i) --> clips the line i in x, adding the remainder to x[i+1]
d = function(x,i) "[<-"(x,i:(j<-i+1),
c(a<-substr(x[i],1,l(x[j])), sub(a,x[j],x[i])))
# a --> clipped x[i], sub(a,x[j],x[i]) --> expanded x[j]
while(!is.na(o(x)))x=d(x,o(x));x
}
这个怎么运作:
(或者换句话说,“多余的”部分会下降,直到所有可能下降的部分都下降为止。)
输入:字符向量。
x<-readLines(textConnection("Programming\nPuzzles\n&\nCode\nGolf"))
f(x)
# [1] "P" "Prog" "&uzz" "Coderam" "Golflesming"