Code Golf: Волна
Задача
Самый короткий код по количеству символов для генерации волны из входной строки.
Волна генерируется путем повышения (line-1) более высокого символа и ухудшения (строка + 1) более низкого символа. Равные символы хранятся в одной строке (без повышения или снижения).
Ввод производится только из строчных символов и цифр, буквы считаются выше цифр.
Тестовые примеры:
Input:
1234567890qwertyuiopasdfghjklzxcvbnm
Output:
z
l x v n
k c b m
j
h
g
y p s f
t u o a d
w r i
9 q e
8 0
7
6
5
4
3
2
1
Input:
31415926535897932384626433832795028841971693993751058209749445923078164062862
Output:
9 9 8 6 6
9 6 8 7 3 3 4 2 4 8 9 88
3 4 5 2 5 5 2 33 3 7 5 2 4 9 9 99 7
1 1 3 2 0 1 7 6 3 3 5 8 8 6
1 1 5 2 9 9 3 7 1 4 6 8
0 0 7 9 5 2 0 0 2 6
4 44 2
Количество кодов включает ввод/вывод (т.е. полную программу).
Ответы
Ответ 1
машинный код x86 (37 байт)
HexDump:
6800B807BF8007BE8200B40EAC3C0D741338D8740A720481EF400181C7A000AB86C3EBE8C3
Запуск в MS-DOS с 50-строчной консолью, вход берется из командной строки.
например.
wave.com 1234567890qwertyuiopasdfghjklzxcvbnm
Загрузите здесь двоичный файл
Обновление: Снято с трех байтов благодаря jrandomhacker
Ответ 2
54 символа, если вы позволяете интерпретатору обрабатывать ввод/вывод.
e=:|:@((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}.)a.i.])
65, чтобы явно прочитать stdin и записать в stdout.
(|:((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}.)a.&i.)~1!:1[3)1!:2[4
e '1234567890qwertyuiopasdfghjklzxcvbnm'
z
l x v n
k c b m
j
h
g
y p s f
t u o a d
w r i
9 q e
8 0
7
6
5
4
3
2
1
e '31415926535897932384626433832795028841971693993751058209749445923078164062862'
9 9 8 6 6
9 6 8 7 3 3 4 2 4 8 9 88
3 4 5 2 5 5 2 33 3 7 5 2 4 9 9 99 7
1 1 3 2 0 1 7 6 3 3 5 8 8 6
1 1 5 2 9 9 3 7 1 4 6 8
0 0 7 9 5 2 0 0 2 6
4 44 2
NB. Look up ASCII codes
ord =: a. i. ]
ord 'p4ssw0rd'
112 52 115 115 119 48 114 100
NB. Going up?
up =: }: < }.
up ord 'p4ssw0rd'
0 1 0 1 0 1 0
NB. Going down?
down =: }: > }.
down ord 'p4ssw0rd'
1 0 0 0 1 0 1
NB. Combine to get ±1
updown =: }: (> - <) }.
updown ord 'p4ssw0rd'
1 _1 0 _1 1 _1 1
NB. Start with 0, follow up with partial sums
sum =: 0 , +/\
sum updown ord 'p4ssw0rd'
0 1 0 0 _1 0 _1 0
NB. Subtract the minimum to get sequence with base at 0
fix =: - <./
fix sum updown ord 'p4ssw0rd'
1 2 1 1 0 1 0 1
NB. For convenience, name this chain of functions
d =: [: fix [: sum [: updown ord
NB. Make spaces before the characters
push =: (#&' ' @ ] , [)"0 d
push 'p4ssw0rd'
p
4
s
s
w
0
r
d
NB. Turn it on its side
|: push 'p4ssw0rd'
w r
p ss 0 d
4
NB. Combine into one named function…
e =: |: @ push
NB. …and inline everything
e =: |:@((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}.)a.i.])
Ответ 3
Самый короткий код по символу для печати "волны" из входной строки.
Console.WriteLine( "a" волна "из входной строки." );
Ответ 4
Perl (94 символа)
144 символа изначально barnaba:
chop($_=<>);$l=length;push(@a," "x$l)for(1..$l*2);$l+=(ord $p<=>ord $_),substr($a[$l],$r++,1)=$p=$_ for(split //);/^\s+$/||print "$_\n" for(@a)
121 символ оптимизации от Криса Лутца:
$_=<>;chop;$a[@a]=" "x$l for 1..($l=length)*2;$l+=$p cmp$_,substr($a[$l],$r++,1)=$p=$_ for split//;/\S/&&print"$_\n"[email protected]
94 символа из дальнейшей оптимизации:
$_=<>;@a=($"x($l=y///c).$/)x(2*$l);s/./substr$a[$l+=$"cmp$&],"@-",1,$"=$&/ge;/\S/&&print [email protected]
Обратите внимание, что в традиционном гольф-клубе Perl обычно добавляется количество переключателей и длина кода (что может помочь здесь несколькими штрихами), но здесь мы используем автономные программы без переключателей.
Ответ 5
C на терминале VT100 (76 символов)
Это работает в моем тесте на FreeSBIE:
o;main(c){for(;(c=getchar())-10;o=c)printf("\33[1%c%c",c<o?66:c>o?65:71,c);}
Но для того, чтобы четко увидеть вывод, вы должны запустить его с чем-то вроде этого:
clear ; printf "\n\n\n\n\n" ; echo the quick brown fox jumps over the lazy dog | ./a.out ; printf "\n\n\n\n\n"
Считается ли это?
Ответ 6
Python (161 символ)
v,s="",raw_input()
m=n=len(s)
r=[' ']*n
q=[r[:]for i in range(2*n)]
for j,i in enumerate(s):
m+=(i<v)-(i>v)
q[m][j],v=i,i
for i in q:
if i!=r:print''.join(i)
Я еще не сделал много, чтобы сжать его. Теперь портируем его на что-то с помощью оператора космического корабля.
Ответ 7
Ruby: 99 bytes
r,a,q,i=[],"",99,0
gets.chars{|x|t=r[q+=a<=>x]||=""
a=x
r[q]+=" "*(i-t.size)+x
i+=1}
puts r.compact
несжатый:
r,a,q,i = [],"",99,0
gets.chars { |x|
t = r[q+=a<=>x] ||= ""
a = x
r[q] += " "*(i-t.size)+x
i += 1
}
puts r.compact
Ответ 8
PHP (138 символов)
<?for($lc=$i=$h=0;"\n"!=$c=fgetc(STDIN);$o[$h]=sprintf("%- {$i}s%s",@$o[$h],$lc=$c),$i++)$h+=$c<$lc?-1:$c>$lc;krsort($o);echo join($c,$o);
'Readable' version:
<?
for (
$last_ch = $i = $level = 0;
"\n" != $ch = fgetc(STDIN);
$out[$level] = sprintf("%- {$i}s%s", @$out[$level], $last_ch = $ch), $i++
)
$level += $ch < $last_ch ? -1 : $ch > $last_ch;
krsort($out);
echo join($ch,$out);
Ответ 9
Python 2.x, теперь до 156 символов:
s=raw_input()
R=range(len(s))
m=[0]
for i in R[1:]:m+=[m[-1]-cmp(s[i],s[i-1])]
for x in range(min(m),max(m)+1):print''.join(m[i]==x and s[i]or' 'for i in R)
Ответ 10
C89 (151 символ)
l[999][999];p;v=500;r;main(c){for(;(c=getchar())>0;
)l[v+=c>p,v-=c<p][++r]=*l[v]=p=c;for(v=999;v--;)for
(c=0;c++<=r;)*l[v]&&putchar(c<=r?32|l[v][c]:10);}
Ответ 11
Haskell, 215 символов. Я публикую это, потому что мне совсем не нравится версия Khoth. Просто написав в достаточно функциональном стиле, я получил значительно более короткую и более читаемую программу IMO. Я на самом деле не пытался сделать его короче, кроме имен переменных и интервалов. Деструктивное обновление массива может сделать его короче, чем реплицирование пробелов.
import Char
import List
main=getLine>>=(putStr.p)
p s=unlines$transpose[z++(y:x)|(m,y)<-zip n s,let(x,z)=splitAt m$replicate(maximum n)' ']
where o=map ord s
n=scanl(+)0$map signum$zipWith(-)(tail o)o
Ответ 12
С#:
using System;
static class A
{
static void Main(string[] a)
{
var s=a[0];var r="";
int i=1,h=0,d=0,c=0,n=s.Length;
var m=new int[n];
m[0]=0;
for(;i<n;i++)
{
c+=Math.Sign(s[i]-s[i-1]);
h=(c>h)?c:h;
d=(c<d)?c:d;
m[i]=c;
}
for(;h>=d;h--)
{
for (c=0;c<n;c++)
r+=(m[c]==h)?s[c]:' ';
r+="\n";
}
Console.Write(r);
}
}
Взвешивается при сжатии 287.
Ответ 13
Perl, 85 символов с переключателями, 96 без
Вызов с -F// -an
переключатели
$q=$"x([email protected]);$,=$/;for(@F){/
/&&[email protected];substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}
Между символами 2-го и 3-го коса есть новая строка. Без переключателей вы можете сделать
$q=$"x([email protected]=split//,<>);$,=$/;for(@C){/
/&&[email protected];substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}
Ответ 14
Haskell (285 символов):
heightDiff x y | x == y = 0
| x < y = -1
| True = 1
heights h (x:y:z)= (x,h):(heights (h+(heightDiff x y) ) (y:z))
heights h [y] = [(y,h)]
makech ((x,h):xs) i = (if i==h then x else ' '):makech xs i
makech [] _ = []
printAll xs = mapM_ (putStrLn . (makech xs)) [(minimum $ map snd xs)..(maximum $ map snd xs)]
main = getLine >>= (printAll . heights 0)
Некоторое сжатие (260 символов):
a x y|x==y=0
|x<y= -1
|True=1
c h (x:y:z)=(x,h):(c(h+(a x y))(y:z))
c h [y]=[(y,h)]
d ((x,h):xs)i=(if i==h then x else ' '):d xs i
d [] _=[]
p xs = mapM_ (putStrLn .(d xs)) [(minimum $ map snd xs)..(maximum $ map snd xs)]
main = getLine >>= (p . c 0)
Ответ 15
Perl, 88 символов
Теперь отредактировано до 88 символов:
$_=<>;
s/.(?=(.))/($"x40).$&.$"x(39+($1cmp$&))/ge;
@_=/.{80}/g;
{say map{chop||die}@_;redo}
Был:
$_=<>;
s/.(?=(.))/$&.$"x(79+($1cmp$&))/ge;
s/^.{40}|.{80}/$&\n/g;
print $& while /.$/gm || s/.$//gm * /\n/;
97 символов (без пробелов). Это не так уж и коротко, но мне интересно, сможет ли кто-то с большим опытом работы с PERL укоротить его дальше. А также выявить любые ошибки. Во второй строке используются пробелы для создания волны, которая падает вертикально, а не горизонтально, на экране ширины ширины 80. Третья строка вставляет строки. Последняя строка переворачивает оси X/Y.
Мне казалось, что последние две строки могут быть чем-то вроде interleave (s/. {80}/g), где interleave чередует массив строк. Но, похоже, не такая функция я надеялся. (Или есть в библиотеке?)
Ответ 16
Первый крик на С#. Вход должен быть представлен как первый аргумент командной строки.
using System;
using C = System.Console;
static class P
{
static void Main(string[] a)
{
var b = a[0];
var l = b.Length;
int y = 0, z = 0;
for (int i = 0; i < l - 1; i++)
{
y += Math.Sign(b[i] - b[i + 1]);
z = Math.Min(y, z);
}
y = 0;
for (int i = 0; i < l - 1; i++)
{
C.SetCursorPosition(i, y - z);
C.Write(b[i]);
y += Math.Sign(b[i] - b[i + 1]);
}
}
}
Это дает 280 байтов в сжатом формате.
using System;using C=System.Console;static class P{static void Main(string[]a){var b=a[0];var l=b.Length;int y=0,z=0;for(int i=0;i<l-1;i++){y+=Math.Sign(b[i]-b[i+1]);z=Math.Min(y,z);}y=0;for(int i=0;i<l-1;i++){C.SetCursorPosition(i,y-z);C.Write(b[i]);y+=Math.Sign(b[i]-b[i+1]);}}}
Попытка номер два с другим подходом.
using System;
using System.Collections.Generic;
static class P
{
static void Main(string[] a)
{
var b = a[0] + "$";
var l = new List<string>();
var y = -1;
for (int i = 0; i < b.Length - 1; i++)
{
if ((y == -1) || (y == l.Count))
{
y = y < 0 ? 0 : y;
l.Insert(y, b.Substring(i, 1).PadLeft(i + 1));
}
else
{
l[y] = l[y].PadRight(i) + b[i];
}
y += Math.Sign(b[i] - b[i + 1]);
}
foreach (var q in l) Console.WriteLine(q);
}
}
Далее цикл можно переписать для использования блока try/catch.
for (int i = 0; i < b.Length - 1; i++)
{
try
{
l[y] = l[y].PadRight(i) + b[i];
}
catch
{
y = y < 0 ? 0 : y;
l.Insert(y, b.Substring(i, 1).PadLeft(i + 1));
}
y += Math.Sign(b[i] - b[i + 1]);
}
Это дает слегка измененные и сжатые 321 байт - чуть больше первой попытки, но много robuster.
using System;static class P{static void Main(string[]a){var b=a[0]+"$";var r=new System.Collections.Generic.List<string>();var y=-1;for(int i=0;i<b.Length-1;i++){try{r[y]=r[y].PadRight(i)+b[i];}catch{y=y<0?0:y;r.Insert(y,b[i].ToString().PadLeft(i+1));}y+=Math.Sign(b[i]-b[i+1]);}foreach(var l in r)Console.WriteLine(l);}}
Ответ 17
PowerShell
Уверен, это можно сделать с гораздо меньшим количеством кода, если кто-то хочет отредактировать это, было бы отлично. Я оставляю его доступным для чтения.
$v = (Read-Host).ToCharArray()
$r = @(0)
for($i = 1; $i -lt $v.length; $i++) {
$p = $i - 1
$r += $r[$p] + [System.Math]::Sign($v[$i] - $v[$p])
$t = [System.Math]::Max($t, $r[$i])
$b = [System.Math]::Min($b, $r[$i])
}
for($i = $t; $i -ge $b; $i--) {
for($x = 0; $x -lt $r.length; $x ++) {
if($r[$x] -eq $i) {
$o += $v[$x]
}
else {
$o += " "
}
}
$o += "`n"
}
$o
Ответ 18
F #, 242 символа:
let F(s:string)=(fun L->let a=Array.init(L*3)(fun _->Array.create L ' ')in Seq.fold(fun(r,p,c)n->let r=r+sign(int p-int n)in a.[r].[c]<-n;r,n,c+1)(L,s.[0],0)s;for r in a do if Array.exists((<>)' ')r then printfn"%s"(new string(r)))s.Length
С добавлением пробелов для упрощения чтения это
let F(s:string) =
(fun L->
let a = Array.init (L*3) (fun _ -> Array.create L ' ') in
Seq.fold (fun (r,p,c) n ->
let r = r + sign(int p-int n) in
a.[r].[c]<-n;
r, n, c+1)
(L, s.[0], 0)
s;
for r in a do
if Array.exists ((<>) ' ') r then
printfn "%s" (new string(r))
) s.Length
Ответ 19
C (157 символов)
Я застрял там пока. Я не думаю, что C будет бить J на этом. Тем не менее, благодаря strager для поддержки 8 символов.
char*p,a[999][80];w,x,y=500;main(c){for(gets(memset(p=*a,32,79920));*p;
a[y][x++]=c=*p++)y+=*p<c,y-=*p>c;for(;++w<998;strspn(p," ")-79&&puts(p))
79[p=a[w]]=0;}
отформатированный:
char *p, /* pointer to current character (1st) or line (2nd) */
a[999][80]; /* up to 998 lines of up to 79 characters */
w, x, y = 500; /* three int variables. y initialized to middle of array */
main(c){
for(gets(memset(p=*a, 32, 79920));
/* 999 * 80 = 79920, so the entire array is filled with space characters.
* memset() returns the value of its first parameter, so the above is
* a shortcut for:
*
* p = *a;
* memset(p, 32, 79920);
* gets(p);
*
* Incidentally, this is why I say "up to 998 lines", since the first
* row in the array is used for the input string.
*
* **** WARNING: Input string must not be more than 79 characters! ****
*/
*p;a[y][x++] = c = *p++) /* read from input string until end;
* put this char in line buffer and in prev
*/
y += *p < c, /* if this char < prev char, y++ */
y -= *p > c; /* the use of commas saves from using { } */
for(;++w < 998; /* will iterate from 1 to 998 */
strspn(p, " ") - 79 &&
/* strspn returns the index of the first char in its first parameter
* that NOT in its second parameter, so this gets the first non-
* space character in the string. If this is the NULL at the end of
* the string (index 79), then we won't print this line (since it blank).
*/
puts(p)) /* write the line out to the screen (followed by '\n') */
79[p = a[w]] = 0; /* same as "(p = a[y])[79] = 0",
* or "p = a[y], p[79] = 0", but shorter.
* Puts terminating null at the end of each line
*/
}
Я не беспокоился о поддержке ввода более 79 символов, так как это вызовет запутанную оболочку на большинстве терминалов.
Ответ 20
Решение Java, не особенно сжатое (теперь модифицированное для чтения из stdin).
public class W
{
public static void main(String[] x)
{
String s = new java.util.Scanner(System.in).nextLine();
int i,j;
int t = s.length();
char[] b = s.toCharArray();
char[][] p = new char[2*t][t];
int q = t;
char v = b[0];
for (i=0; i<2*t; i++)
{
for (j=0; j<t; j++)
{
p[i][j] = ' ';
}
}
p[q][0] = v;
String z = new String(p[0]);
for (i=1; i<t; i++)
{
char c = b[i];
int d = (c == v) ? 0 : (c > v ? -1 : 1);
q += d;
p[q][i] = c;
v = c;
}
for (i=0; i<2*t; i++)
{
String n = new String(p[i]);
if (!n.equals(z))
{
System.out.println(n);
}
}
}
}
Ответ 21
С# (564 символа кода)
using System;
class Program {
static void Main(string[] args) {
var input = args[0];
int min = 0, max = 0;
var heights = new int[input.Length];
for (var i = 1; i < input.Length; i++) {
heights[i] = heights[i-1] + (input[i] > input[i-1] ? 1 : (input[i] < input[i-1] ? -1 : 0));
min = Math.Min(min, heights[i]);
max = Math.Max(max, heights[i]);
}
for (var row = max; row >= min; row--, Console.WriteLine())
for (var col = 0; col < input.Length; col++)
Console.Write(heights[col] == row ? input[col] : ' ');
}
}
Компактный: (324 символа кода)
using System;class A{static void Main(string[] args){var I=args[0];int M=0,X=0;var H=new int[I.Length];for(var i=1;i<I.Length;i++){H[i]=H[i-1]+(I[i]>I[i-1]?1:(I[i]<I[i-1]?-1:0));M=Math.Min(M,H[i]);X=Math.Max(X,H[i]);}for(var r=X;r>=M;r--,Console.WriteLine())for(var c=0;c<I.Length;c++)Console.Write(H[c]==r?I[c]:' ');}}
Использование трюков из комментариев (283 символа):
using System;class A{static void Main(string[] a){var I=a[0];int M=0,X=0,i=1,r,h,c=0,l=I.Length;var H=new int[l];for(;i<l;i++){h=H[i-1]+(I[i]>I[i-1]?1:(I[i]<I[i-1]?-1:0));H[i]=h;M=M<h?M:h;X=x>h?X:h;}for(r=X;r>=M;r--,Console.Write('\n'))for(;c<l;c++)Console.Write(H[c]==r?I[c]:' ');}}
Ответ 22
Perl 5.10
159, наиболее "удобная" версия:
perl -nE'chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;%e=();for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}'
Следующая версия - 153, но вы можете ввести только одну строку. Чтобы ввести более одного, необходимо перезапустить программу. Правила неясны в отношении того, разрешено ли это или нет, но я решил, что лучше всего разместить обе версии в любом случае:
perl -nE'chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}'
И вот версия символа 149 - это script, а не однострочный shell, а также работает только для одной строки ввода, но не будет продолжать принимать вход после этой первой строки, что, вероятно, хорошо:
$_=<>;chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}
Ни один из них не так короток, как уже появилось решение Perl, но, похоже, они, похоже, превзошли Python и Ruby. И кроме того, там больше, чем один способ сделать это.
Ответ 23
F #, 235 символов
Совершенно другая стратегия спасла несколько символов по сравнению с моим другим решением.
let F(s:string)=(fun L->let _,_,h=Seq.fold(fun(p,h,l)n->let r=h-sign(int n-int p)in n,r,r::l)(s.[0],0,[0])s in for r in Seq.min h..Seq.max h do printfn"%s"(new string(Array.init L (fun c->if r=h.[L-1-c]then s.[c]else ' '))))s.Length
С пробелами:
let F(s:string) =
(fun L->
let _,_,h = Seq.fold (fun (p,h,l) n ->
let r = h - sign(int n-int p) in
n,r,r::l) (s.[0],0,[0]) s in
for r in Seq.min h..Seq.max h do
printfn "%s" (new string(Array.init L (fun c ->
if r=h.[L-1-c] then s.[c] else ' ')))
) s.Length
Ответ 24
С# 545 байт несжатого
using System;
using System.Linq;
class Program{
static void Main(string[] b){
var s = b[0];
var t = new System.Collections.Generic.Dictionary<int, string>();
int y=0, p=0;
for (int i = 0; i < s.Length; i++){
y += Math.Sign(s[i] - p);
p = s[i];
if (!t.ContainsKey(y))
t.Add(y, "");
t[y] = t[y].PadRight(i) + s[i];
}
foreach (var v in t.OrderBy(a => -a.Key))
Console.WriteLine(v.Value);
}
}
Ответ 25
Ruby: 109 байт, считая символы новой строки!!
s=gets
r,a,q,i=[],s[0,1],99,0
s.chars{|x|q+=a<=>x
a=x
t=r[q]||=""
r[q]+=" "*(i-t.size)+x
i+=1}
puts r.compact
несжатый:
s = gets
r,a,q,i = [],s[0,1],99,0
s.chars { |x|
q += a<=>x
a = x
t = r[q] ||= ""
r[q] += " "*(i-t.size)+x
i += 1
}
puts r.compact
Ответ 26
Groovy (195 символов)
Тест
s="1234567890qwertyuiopasdfghjklzxcvbnm"
короткое
=(s=~/./).collect{(char)it}
e=' ';x=0;l=[];u=[]
w.eachWithIndex({it,n->
if(l.size()>x){l[x]+=e*(n-u[x]-1)+it;u[x]=n}else{l+=e*n+it;u+=n}
if(w[n+1]>it)x++else x--;})
l.reverse().each({println it})
Ответ 27
PHP: 108 символов
<?while(-1<$a=fgetc(STDIN)){$d+=$a<$b^-($a>$b);$r[$d].=' ';$r[$d][$k++]=$b=$a;}ksort($r);echo join("\n",$r);
Считываемая версия:
<?
while(-1<$a=fgetc(STDIN)){
$d+=$a<$b^-($a>$b);
$r[$d].=' ';
$r[$d][$k++]=$b=$a;
}
ksort($r);
echo join("\n",$r);
Ответ 28
Golfscript - 65 символов
' ': :c;1/:a,.+,{:N;a,a{:@c<[email protected]:c<-.N=[ c]\=}%.[n+'']\$-1= ==\;}%
Генерировать волновую линию по строке
{:N;a,a{:@c<[email protected]:c<-.N=[ c]\=}%
Отфильтруйте пустые строки
.[n+'']\$-1= ==\
Ответ 29
ASL: 73
args1[,;{ch},1_]@1]o o>:><-0 0a:/+,/&-;{()@:'{" "`}}@;{};;{(){`}#`}" ":|P
Я просто перевел J-решение в ASL.
Ответ 30
XQuery
(257 bytes)
declare variable$i external;let$c:=string-to-codepoints($i),$h:= for$x at$p in$c
return sum(for$x in 1 to$p let$d:=$c[$x]-$c[$x -1]return(-1[$d>0],1[$d<0]))return
codepoints-to-string(for$p in min($h)to max($h),$x at$q
in($c,10)return(32[$h[$q]!=$p],$x)[1])
Так как XQuery является чисто декларативным, мне пришлось подделать ввод как переданный во внешнюю переменную. Вот командная строка для запуска этого с помощью XQSharp:
xquery wave.xq !method=text i='1234567890qwertyuiopasdfghjklzxcvbnm'
Если строка была передана в качестве элемента контекста, то это можно было бы еще уменьшить, но установка элемента контекста в значение не node не поддерживается со всеми реализациями XQuery (а не с помощью инструмента командной строки XQSharp ):
let$c:=string-to-codepoints(.),$h:= for$x at$p in$c return sum(for$x in 1 to$p
let$d:=$c[$x]-$c[$x -1]return(-1[$d>0],1[$d<0]))return codepoints-to-string(for$p
in min($h)to max($h),$x at$q in($c,10)return(32[$h[$q]!=$p],$x)[1])
Всего 228 байт.