language-agnostic code-golf rosetta-stone

language agnostic - Code Golf: La ola



language-agnostic code-golf (30)

El reto

El código más corto por carácter cuenta para generar una onda desde la cadena de entrada.

Se genera una onda elevando (línea-1) un carácter más alto, y degradando (línea + 1) un carácter inferior. Los caracteres iguales se mantienen en la misma línea (sin elevación ni degradación).

La entrada se realiza con caracteres y minúsculas, las letras se consideran más altas que los números.

Casos de prueba:

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

El recuento de códigos incluye entrada / salida (es decir, programa completo).


El código más corto por carácter cuenta para imprimir una ''onda'' desde la cadena de entrada.

Console.WriteLine ("a ''wave'' desde la cadena de entrada.");


F #, 235 caracteres

Una estrategia completamente diferente ahorró algunos caracteres en comparación con mi otra solución.

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

Con espacios en blanco:

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


F #, 242 caracteres:

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

Con espacios en blanco añadidos para una lectura más fácil, es

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


Golfscript - 65 caracteres

'' '': :c;1/:a,.+,{:N;a,a{:@c<+c@:c<-.N=[ c]/=}%.[n+'''']/$-1= ==/;}%

Genera la onda línea por línea

{:N;a,a{:@c<+c@:c<-.N=[ c]/=}%

Filtra las líneas en blanco

.[n+'''']/$-1= ==/


ASL: 73

args1[,;{ch},1_]@1]o o>:><-0 0a:/+,/&-;{()@:''{" "`}}@;{};;{(){`}#`}" ":|P

Acabo de traducir la solución J en ASL.


C89 (151 caracteres)

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);}


Groovy (195 caracteres)

prueba

s="1234567890qwertyuiopasdfghjklzxcvbnm"

corto

=(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})


PHP (138 caracteres)

<?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);

Versión ''legible'' :

<? 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);


PHP: 108 caracteres

<?while(-1<$a=fgetc(STDIN)){$d+=$a<$b^-($a>$b);$r[$d].='' '';$r[$d][$k++]=$b=$a;}ksort($r);echo join("/n",$r);

Versión legible:

<? while(-1<$a=fgetc(STDIN)){ $d+=$a<$b^-($a>$b); $r[$d].='' ''; $r[$d][$k++]=$b=$a; } ksort($r); echo join("/n",$r);


Perl (94 caracteres)

144 caracteres originalmente por 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 caracteres de la optimización de Chris Lutz:

$_=<>;chop;$a[@a]=" "x$l for 1..($l=length)*2;$l+=$p cmp$_,substr($a[$l],$r++,1)=$p=$_ for split//;//S/&&print"$_/n"for@a

94 caracteres de optimización adicional:

$_=<>;@a=($"x($l=y///c).$/)x(2*$l);s/./substr$a[$l+=$"cmp$&],"@-",1,$"=$&/ge;//S/&&print for@a

Tenga en cuenta que en el golf tradicional de Perl, uno normalmente agrega el número de interruptores y la longitud del código (lo que ayudaría aquí con unos pocos golpes), pero aquí estamos usando programas independientes sin interruptores.


Perl 5.10

159 caracteres, la mayoría de las versiones "fáciles de usar":

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}''

La siguiente versión tiene 153 caracteres, pero solo puede ingresar una línea. Para ingresar más de uno, debe reiniciar el programa. Las reglas no están claras si esto está permitido, pero pensé que sería mejor publicar ambas versiones de todos modos:

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}''

Y aquí hay una versión de 149 caracteres: esta es una secuencia de comandos en lugar de una línea única, y también funciona para una sola línea de entrada, pero no continuará aceptando entrada después de esa primera línea, lo cual es probablemente una buena cosa. :

$_=<>;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}

Ninguno de estos es tan breve como la solución de Perl ya publicada, pero sin duda parecen vencer a Python y Ruby. Y además, hay más de una forma de hacerlo.


Perl, 85 caracteres con interruptores, 96 sin

Invocar con -F// -an interruptores

$q=$"x($n=@F);$,=$/;for(@F){/ /&&print@O;substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}

Hay una nueva línea entre los caracteres de barra 2a y 3ra. Sin interruptores puedes hacer

$q=$"x($n=@C=split//,<>);$,=$/;for(@C){/ /&&print@O;substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}


Potencia Shell

Estoy seguro de que esto se puede hacer con mucho menos código, si alguien quiere editar eso sería excelente. Lo dejo legible.

$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


Ruby: ¡¡109 bytes, contando personajes nuevos !!

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

Sin comprimir

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


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

Sin comprimir

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


código de máquina x86 (37 bytes)

Hexdump:

6800B807BF8007BE8200B40EAC3C0D741338D8740A720481EF400181C7A000AB86C3EBE8C3

Ejecutar en MS-DOS con consola de línea 50, la entrada se toma desde la línea de comandos.

P.ej

wave.com 1234567890qwertyuiopasdfghjklzxcvbnm

Descargar binario aquí

Actualización: afeitado tres bytes gracias a jrandomhacker


J

54 caracteres, si permite que el intérprete maneje la entrada / salida.

e=:|:@((#&'' ''@],[)"0[:(-<./)0,[:+//[:(}:(>-<)}.)a.i.])

65 para leer explícitamente de stdin y escribir en 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.])


C (157 caracteres)

Estoy atrapado allí por el momento. No creo que C venza a J en este caso. Gracias a Strager por ayudar a recortar 8 caracteres, sin embargo.

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;}

Formateado:

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''s 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''s 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 */ }

No me molesté en admitir entradas de más de 79 caracteres, ya que eso causaría un efecto confuso en la mayoría de los terminales.


C en una terminal VT100 (76 caracteres)

Esto funciona en mi prueba en FreeSBIE:

o;main(c){for(;(c=getchar())-10;o=c)printf("/33[1%c%c",c<o?66:c>o?65:71,c);}

Pero para ver claramente el resultado, debe ejecutarlo con algo como esto:

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"

¿Esto cuenta?


Python (161 caracteres)

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)

Aunque no he hecho mucho para comprimirlo. Transmitirlo a algo con un operador de nave espacial ahora.


DO#:

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); } }

Pesa a 287 comprimidos.


Haskell (285 caracteres):

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)

Alguna compresión (260 caracteres):

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)


Haskell, 215 caracteres. Estoy publicando esto porque no me gusta la versión de Khoth. Simplemente escribiendo en un estilo razonablemente funcional terminé con un programa significativamente más corto e IMO más legible. En realidad, no he intentado hacerlo corto aparte de los nombres de las variables y el espaciado. La actualización destructiva de una matriz puede hacerla más corta que la duplicación de espacios.

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


Python 2.x, ahora hasta 156 caracteres:

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)


Un primer grito en C #. La entrada debe suministrarse como primer argumento de linie de comando.

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]); } } }

Esto produce 280 bytes en comprimido desde.

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,yz);C.Write(b[i]);y+=Math.Sign(b[i]-b[i+1]);}}}

Intenta el número dos con un enfoque diferente.

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); } }

El ciclo puede ser reescrito para usar un bloque 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]); }

Esto produce 321 bytes ligeramente modificados y comprimidos, un poco más que el primer intento, pero con mucho robustez.

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);}}


Una solución Java, no particularmente comprimida (ahora modificada para leer de 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); } } } }


C # (564 caracteres de código)

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] : '' ''); } }

Compactado: (324 caracteres de código)

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]:'' '');}}

Usando trucos de comentarios (283 caracteres):

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]:'' '');}}


C # 545 byte descomprimido

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); } }


Perl, 88 caracteres

Ahora, editado a 88 caracteres:

$_=<>; s/.(?=(.))/($"x40).$&.$"x(39+($1cmp$&))/ge; @_=/.{80}/g; {say map{chop||die}@_;redo}

Estaba:

$_=<>; s/.(?=(.))/$&.$"x(79+($1cmp$&))/ge; s/^.{40}|.{80}/$&/n/g; print $& while /.$/gm || s/.$//gm * //n/;

97 caracteres (omitiendo espacios). No es tan corto, pero me pregunto si alguien con más experiencia con PERL puede acortarlo aún más. Y también detectar cualquier error. La segunda línea usa espacios para hacer una onda que cae verticalmente en lugar de horizontalmente, en una pantalla de envoltura de 80 anchos. La tercera línea inserta linebreaks. La última línea invierte los ejes X / Y.

Originalmente me había preguntado si las últimas dos líneas podrían ser algo así como intercalar (s /. {80} / g) donde intercalar intercala una matriz de cadenas. Pero parece que no hay esa función que esperaba. (¿O hay una biblioteca?)


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])

Como XQuery es puramente declarativo, he tenido que falsificar la entrada como una variable externa. Aquí está la línea de comando para ejecutar esto con XQSharp:

xquery wave.xq !method=text i=''1234567890qwertyuiopasdfghjklzxcvbnm''

Si la cadena se transfirió como el elemento de contexto, esto podría reducirse aún más, pero no se admite establecer el elemento de contexto en un valor no nodo con todas las implementaciones XQuery (y no con la herramienta de línea de comandos 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])

Solo 228 bytes.