Le code le plus court par nombre de caractères qui produira l'équivalent numérique d'une chaîne de colonne Excel.
Par exemple, la colonne A
est 1, B
est 2, ainsi de suite et ainsi de suite. Une fois que vous appuyez sur Z
, la colonne suivante devient AA
, puis AB
et ainsi de suite.
A: 1
B: 2
AD: 30
ABC: 731
WTF: 16074
ROFL: 326676
Le nombre de codes comprend les entrées/sorties (c'est-à-dire le programme complet).
$_=()=A..$_
Usage:
$ echo -n WTF | Perl -ple '$_=()=A..$_'
16074
Réduit à 17 en utilisant echo -n pour éviter un appel chop
.
Réduit à 15 en utilisant say au lieu de print.
Réduit à 11 en utilisant -p au lieu de dire.
Explication: A
est évalué dans le contexte d'une chaîne et A..$_
Crée une liste commençant par "A" et incrémentant la chaîne jusqu'à la chaîne d'entrée. Perl interprète l'opérateur ++
(Et donc ..
) Sur les chaînes dans un contexte alphabétique, donc par exemple $_="AZ";$_++;print
Affiche BA
.
=()=
(aka opérateur "goatse" ) force une expression à être évaluée dans le contexte de la liste, et retourne le nombre d'éléments retournés par cette expression, c'est-à-dire $scalar = () = <expr>
correspond à @list = <expr>; $scalar = @list
.
Utilisez le bon outil pour le travail:
=COLUMN()
26#.64-~av
Exemple:
26#.64-~av 'WTF'
16074
Explication:
av
renvoie une liste des index ascii de chacun des caractères de son argument, donc par exemple av'ABC'
résultats 65 66 67
.64-~
.#.
verbe.,[>>>[->>+++++[-<+++++>]<+<]>[-<+>]<<++++++++[<++++++++>-]<[<->-]<[>>>+<<<-],]>>>
,[ // get character input into p[0], enter loop if it isn't null (0)
>>>[->>+++++[-<+++++>]<+<] // take what's in p[3] and multiply by 26, storing it in p[4]
>[-<+>] // copy p[4] back to p[3]
<<++++++++[<++++++++>-]< // store 64 in p[1]
[<->-]< // subtract p[1], which is 64, from the input char to get it's alphabetical index
[>>>+<<<-] // add p[0] to p[3]
,] // get another character and repeat
>>> // move to p[3], where our final result is stored
Vous remarquerez donc que je n'ai pas réellement converti la valeur numérique en une chaîne ascii pour l'impression. Cela ruinerait probablement le plaisir. Mais j'ai fait la faveur de déplacer le pointeur vers la cellule avec le résultat, donc au moins c'est utile pour la machine.
Hé, qu'est-ce que tu sais, j'ai battu C #!
p ('A'..$_).count
Usage:
$ echo -n ROFL | Ruby -n a.rb 326676 $ Echo -n WTF | Ruby -n a.rb 16074 $ Echo -n A | Ruby -n a.rb 1
13 caractères
Mettez la valeur dans x
:
x←'WTF'
puis calculez-le avec:
26⊥(⎕aV⍳x)-65
La seule raison pour laquelle J m'a battu est à cause des parenthèses. Je pense qu'il devrait y avoir un moyen de le réorganiser pour éviter d'en avoir besoin, mais la journée a été longue. Des idées?
(Hé, vous les programmeurs Perl avec vos 30+ solutions de personnages sont si mignons!)
Prend en charge jusqu'à XFD:
=COLUMN(INDIRECT(A1&"1"))
Installation:
Usage:
Prend également en charge ROFL:
(A2) =MAX(B:B)
(B2) =IFERROR(26*B1+CODE(MID(A$1,ROW()-1,1))-64,0)
Installation:
Usage:
using System.Linq;class P{static void Main(string[]a){System.Console.Write(
a[0].Aggregate(0,(t,c)=>(t+c-64)*26)/26);}}
Non golfé:
using System.Linq;
class P
{
static void Main(string[] a)
{
System.Console.Write(a[0]
.Aggregate(0, (t, c) => (t + c - 64) * 26) / 26);
}
}
[0]\+{31&\26*+}*
$ echo -n WTF | ./golfscript.rb Excel.gs
16074
$ echo -n ROFL | ./golfscript.rb Excel.gs
326676
main=interact$show.foldl(\x->(26*x-64+).fromEnum)0
Usage:
~:166$ echo -n "ROFL" | ./a.out
326676
~:167$ echo -n "WTF" | ./a.out
16074
26/:1+.Q.A?
Explication:
.Q.A
est défini dans k4 - c'est le vecteur "ABC...XYZ"
?
est l'opérateur de recherche - l'index de la première correspondance pour les éléments de l'argument y dans l'argument x26/:
pour convertir en base 26Une mise en garde - cela ne fonctionnera que lorsque les types répertoriés sont transmis:
26/:1+.Q.A? "AD"
30
26/:1+.Q.A? "WTF"
16074
mais:
26/:1+.Q.A? ,"A"
1
s=0
for c in raw_input():s=26*s+ord(c)-64
print s
Vous pouvez également remplacer raw_input()
par input()
pour réduire le nombre de caractères de 4, mais cela nécessite alors que l'entrée contienne des guillemets.
Et voici un sous-programme qui affiche 47 caractères:
f=lambda x:len(x)and 26*f(x[:-1])+ord(x[-1])-64
function a(p)Array.reduce(p,function(t,d)t*26+d.charCodeAt()-64,0)
function a(p)(t=0,p.replace(/./g,function(d)t=t*26+d.charCodeAt()-64),t)
function a(p){t=0;p.split("").map(function(d){t=t*26+d.charCodeAt(0)-64});return t}
function a(p){r=0;t=1;l=p.length;for(i=0;i<l;i++){r+=(p.charCodeAt(l-1-i)-64)*t;t*=26}return r}
function a(p,i){i=i||0;l=p.length;return p?(p.charCodeAt(l-1)-64)*Math.pow(26,i)+a(p.slice(0,l-1),i+1):0}
Usage:
a("A") // 1
a("B") // 2
a("AD") // 30
a("ABC") // 731
a("WTF") // 16074
a("ROFL") // 326676
[char[]]$args[($s=0)]|%{$s=$s*26+$_-64};$s
Scala, 30 caractères
print((0/:args(0))(_*26+_-64))"
Exemple:
C:\>scala -e "print((0/:args(0))(_*26+_-64))" AD
30
(defun x(s)(reduce(lambda(x y)(+(* 26 x)y))(map 'vector(lambda(b)(-(char-code b)(char-code #\A)-1))s)))
Agréable. J'ai écrit ma propre version de cela avec un peu plus d'explications il y a longtemps à http://aboutdev.wordpress.com/2009/12/19/excelcification-brain-teaser-code/ . Bien que ce ne soit pas tout à fait une version optimisée!
FYI. L'arithmétique de base 26 est appelée hexavigesimal et la colonne maximale d'Excel est [~ # ~] xfd [~ # ~] qui se convertit en 16383 (en utilisant 0 comme première cellule) qui est par coïncidence exactement 2 ^ 14 cellules .
Quelqu'un peut-il deviner pourquoi c'est 2 ^ 14 ??
s;main(c){while(c=getchar()+1)s=26*s+c-65;printf("%d",s);}
L'entrée (stdin) doit contenir uniquement A-Z, aucun autre caractère (y compris les retours à la ligne) n'est autorisé.
Pas de concours par rapport à Perl, Ruby et APL mais une amélioration par rapport aux autres réponses C #/Java données jusqu'à présent.
Cela utilise règle de Horner .
class C{static void Main(string[]a){int t=0;foreach(var c in a[0]){t=(t+c-64)*26;}System.Console.Write(t/26);}}
LISP commun, 86 caractères.
(defun z(s)(let((a 0))(map nil(lambda(v)(setf a(+(* 26 a)(digit-char-p v 36)-9)))s)a))
Python - 63 caractères
>>> f = lambda z: réduire (lambda x, y: 26 * x + y, [ord (c) -64 pour c dans z])
>>> f ('ROFL')
326676
map$\=26*$\-64+ord,pop=~/./g;print
Merci à mobrule pour plusieurs suggestions.
Clojure:
user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "AD"))
30
user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "ROFL"))
326676
51 caractères, plus le nombre de caractères dans la chaîne d'entrée.
using System;class P{static void Main(string[]a){var r=0d;int j=0,i=a[0].
Length;while(i-->0)r+=(a[0][i]-64)*Math.Pow(26,j++);Console.WriteLine(r);}}
Non golfé:
using System;
class P
{
static void Main(string[] a)
{
var r = 0d;
int j = 0, i = a[0].Length;
while (i-- > 0)
r += (a[0][i] - 64) * Math.Pow(26, j++);
Console.WriteLine(r);
}
}
C:
int r=0;
while(*c)r=r*26+*c++-64;
La chaîne est stockée dans "c", la valeur est dans "r".
p'A'.upto(gets).count
Tests:
$ echo -n A| Ruby x.rb
1
$ echo -n WTF| Ruby x.rb
16074
$ echo -n ROFL| Ruby x.rb
326676
polyval(input('')-64,26)
Usage:
>> polyval(input('')-64,26)
(after pressing enter) 'WTF'
ans =
16074
Remarque: Vous pouvez le réduire à 16 caractères si vous pré-stockez la chaîne dans x
, mais je pensais que c'était de la triche:
>> x = 'WTF'
x =
WTF
>> polyval(x-64,26)
ans =
16074
LISP commun, 81 caractères
(defun y(s)(reduce(lambda(x y)(+(* 26 x)(-(char-code y)64)))s :initial-value 0))
C'est drôle qu'en tant que nouvel utilisateur, je puisse poster ma propre réponse mais pas commenter celle de quelqu'un d'autre. Oh, excuses si je fais ça mal!
en VBA, je suis descendu à 98
Sub G(s)
Dim i, t
For i = 0 To Len(s) - 1
t = t + ((Asc(Left(Right(s, i + 1), 1)) - 64)) * ((26 ^ i))
Next
MsgBox t
End Sub
$n=$argv[1];$s=$i=0;while($i<strlen($n))$s=$s*26+ord($n[$i++])-64;echo$s;
Usage:
php -r '$n=$argv[1];$s=$i=0;while($i<strlen($n))$s=$s*26+ord($n[$i++])-64;echo$s;' AA
> 27
class C{public static void main(String[]a){int r=0;for(int b:a[0].getBytes())r=26*r+b-64;System.out.print(r);}}
p('A'..$*[0]).count
Usage:
$ Ruby a.rb ABC
731
wazoox:
echo -n WTF | Perl -plein '$ = ( A .. $) =='
Cela imprime une nouvelle ligne afin que la réponse soit plus lisible sur le Shell.
Applescript: 188
Voici l'applescript requis en 188 caractères, qui est une langue très difficile à rendre non verbeuse. C'est aussi la réponse la plus longue de toutes les langues jusqu'à présent. Si quelqu'un sait comment le raccourcir, partagez-le.
lors de l'exécution s régler {o, c} sur {0, 0} répéter avec i à l'inverse des caractères de (l'élément 1 de s) définir m à 26 ^ c comme entier régler c à c + 1 régler o à o + ((nombre ASCII de i) - 64) * m répéter la fin moyen détourné
Usage:osascript /path/to/script.scpt ROFL
PHP: 56 55 caractères
for($i='a';$i++!=strtolower($argv[1]);@$c++){}echo++$c;
PHP: 44 43 caractères uniquement pour les lettres majuscules
for($i='A';$i++!=$argv[1];@$c++){}echo++$c;
for($a=A;++$c,$a++!=$argv[1];);echo$c;
utilisation, par ex.
php -r 'for($a=A;++$c,$a++!=$argv[1];);echo$c;' WTF
with(Prompt())for(l=length,i=0,v=i--;++i<l;)v+=(charCodeAt(l-1-i)-64)*Math.pow(26,i);alert(v)
Stockez la chaîne souhaitée dans la variable w:
w←'rofl'
En supposant que les caractères sont en minuscules:
26⊥⎕a⍳w
En supposant que les caractères sont en majuscules:
26⊥⎕A⍳w
Cas mixte ou incertain (14 caractères, mais pourrait éventuellement être amélioré):
26⊥⊃⌊/⎕a⎕A⍳¨⊂w
Smalltalk arguments first reverse inject:0into:[:o :e|o*26+e digitValue]
x=0 for c in(...):gfind(".")do x=x*26-64+c:byte()end print(x)
chomp($n=<>);@c=split(//,uc($n));$o=64;$b=0;$l=$#c;for($i=$l;$i>=0;$i--){$b+=((26**($l-$i))*(ord($c[$i])-$o));}print$b;
Usage:
vivin@serenity ~/Projects/code/Perl/excelc
$ echo WTF | Perl e.pl
16074
vivin@serenity ~/Projects/code/Perl/excelc
$ echo ROFL | Perl e.pl
326676
Je suis sûr que certains gourous de Perl ici peuvent trouver quelque chose de beaucoup plus petit.
chop($l=<>);$_=A;$.++,$_++while$_ ne$l;die$.,$/
OOBasic: 178 caractères, sans compter les espaces blancs d'indentation
Cette version passe tous les cas de test. Je soupçonne qu'il serait plus efficace de jouer au golf s'il "ne profitait pas" du fait qu'il existe un tableur utilisant ce système de numérotation. Voir les notes sur la version originale ci-dessous pour savoir pourquoi ce n'est pas particulièrement utile. Je n'ai pas essayé très fort de réduire le score.
Notez également que cela ne fonctionnera que s'il est exécuté en tant que macro à partir d'une feuille de calcul OO calc, pour des raisons évidentes.
Function C(st as String) as Long
C = 0
while len(st)
C = C*26 + ThisComponent.Sheets(0).getCellRangeByName(left(st,1) &"1").CellAddress.Column+1
st = mid(st,2)
wend
End Function
OOBasic (OpenOffice Basic), trop de caractères (124):
Function C(co As String) As Long
C = ThisComponent.Sheets(0).getCellRangeByName(co &"1").CellAddress.Column+1
End Function
Limites:
Remarques:
Quoi qu'il en soit, la saisie de =C("A")
, =C("ABC")
, etc. dans une cellule fonctionne pour les quatre premiers cas de test; les deux derniers donnent des erreurs.
F # (37 caractères):
Seq.fold (fun n c -> int c-64+26*n) 0
public class A{public static void main(String[] z){int o=0,c=0;for(int i=z[0].length()-1;i>=0;i--,c++)o+=(z[0].charAt(i)-64)*Math.pow(26,c);System.out.println(o);}}
public class A
{
public static void main(String[] z)
{
int m,o=0,c=0;
for(int i=z[0].length()-1;i>=0;i--,c++)
{
m=(int)Math.pow(26,c);
o+=(z[0].charAt(i)-64)*m;
}
System.out.println(o);
}
}
Suppose une entrée en majuscule (via un argument de ligne de commande). L'approche évidente sans astuces.
filtre: 97 caractères
{ read c;i=0;while [ $c ];do eval s=({A..${c:0:1}});i=$((i*26+${#s[@]}));c=${c:1};done;echo $i;}
Usage:
echo ROFL | { read c;i=0;while [ $c ];do eval s=({A..${c:0:1}});i=$((i*26+${#s[@]}));c=${c:1};done;echo $i;}
326676
fonction: 98 caractères
C(){ i=0;while [ $1 ];do eval s=({A..${1:0:1}});i=$((i*26+${#s[@]}));set -- ${1:1};done;echo $i;}
Usage:
C ROFL
326676
Explication de la version du filtre:
read c;i=0;
Initialisez la colonne et le total.
while [ $c ];do
alors qu'il reste des caractères de colonne
eval s=({A..${c:0:1}});
${c:0:1}
Renvoie le premier caractère de la colonne; s=({A..Z})
fait de s un tableau contenant les lettres de A à Z
i=$((i*26+${#s[@]}));
$((...))
encapsule une évaluation arithmétique; ${#s[@]}
Est le nombre d'éléments dans le tableau $ s
c=${c:1};done;
${c:1}
Correspond aux caractères de $ c après le premier. done
termine la boucle while
echo $i
euh j'oublie
mieux mais douteux
La suppression des 5 caractères "écho" entraînera la sortie pour une entrée de "ROFL" étant
326676: command not found
De plus, le i=0
N'est probablement pas nécessaire si vous êtes sûr que cette variable n'est pas définie dans votre shell actuel.
Facteur: 47 caractères
reverse [26 swap ^ swap 64 - *] somme de l'index de la carte
Ma solution Javascript est juste 82 caractères de long et utilise Integer.parseInt avec Radix 36. Ce serait bien si quelqu'un pouvait l'ajouter à la section Javascript de ce fil! :-)
a=function(b){t=0;b.split('').map(function(n){t=parseInt(n,36)-9+t*26});return t};
p ("A"..$*[0]).to_a.size
Josl en 48 caractères
main 0 0 argv each 64 - swap 26 * + next print
Exemples:
$ josl numequiv.j A
1
$ josl numequiv.j ABC
731
$ josl numequiv.j ROFL
326676
Lecture à partir d'une entrée standard:
main 0 STDIN read-line each 64 - swap 26 * + next print
PHP:
<?$t=0;$s=str_split($argv[1]);$z=count($s);foreach($s as$v){$z--;$t+=(ord($v)-64)*pow(26,$z);}echo$t?>
sage: php filename.php ROFL
sorties: 326676
Prolog: 49 caractères
c ([], A, A). c ([H | T], I, R): - J est H-64 + I * 26, c (T, J, R).
En utilisant le code ci-dessus:
| ? - c ("WTF", 0, R). R = 16074? oui | ? - c ("ROFL", 0, R). R = 326676? Oui
(fait le contraire)
dc
ne peut pas gérer la saisie de caractères, j'ai donc codé le contraire: entrez le numéro de colonne et affichez le nom de la colonne:
?[26~64+rd0<LP]dsLxP
dc exccol.dc 326676 ROFL
Matlab 38 caractères
Fonctionne uniquement avec des lettres majuscules. Je ne sais pas si cela doit aussi fonctionner avec des minuscules (aucun dans l'exemple).
x=input('')'-64;26.^(size(x)-1:-1:0)*x
Si les nouvelles lignes ne comptent pas que 37 (en omettant le point-virgule):
x=input('')'-64
26.^(size(x)-1:-1:0)*x
Je vois que Matlab bat beaucoup de langues. Qui s'attendrait à ça.
Exemple:
Input: 'ROFL' (dont forget the '' )
Output: ans = 326676
php 29 caractères:
while($i++!=$t)$c++;echo$c+1;
en utilisant des listes de compréhension:
s=input()
print sum([((26**(len(s)-i-1))*(ord(s[i])-64)) for i in range(len(s))])
26_sv -64+_ic
Usage:
26_sv -64+_ic"ROFL"
326676
Explication:
("WTF"). Colonne
reduce(lambda a,b:a*26+ord(b)-64,raw_input(),0)
fonctionne uniquement sur les lettres majuscules
Python
import string
letters = string.uppercase
colnum = lambda s: sum((letters.index(let)+1)*26**idx for idx, let in enumerate(s[::-1]))
print colnum('WTF')
# 16074
print colnum('ROFL')
# 326676
Elang, 53/78
Shell, 53 caractères:
F=fun(S)->lists:foldl(fun(C,A)->A*26+C-64end,0,S)end.
Module, 78 caractères:
-module(g).
-export([f/1]).
f(S)->lists:foldl(fun(C,A)->A*26+C-64end,0,S).
soit e2n (c: chaîne) = c |> Seq.map (fun x -> (int) x - 64) |> Seq.reduce (fun e a -> a * 26 + e)
Aller: 106 caractères
Ce n'est pas la plus courte de toutes les langues. Mais il peut être le plus court de C, C++, Java et C #.
package main
import("os"
"fmt")
func main(){t:=0
for _,c := range os.Args[1]{t=t*26+c-64}
fmt.Println(t)}
Version formatée:
package main
import (
"os"
"fmt"
)
func main() {
t := 0
for _, c := range os.Args[1] {
t = t*26 + c - 64
}
fmt.Println(t)
}
J'échoue aussi au vrai golf.
Private Sub CB1_Click()
Dim C, S
Range("A1").Select
Do
S = Len(ActiveCell)
x = 0
C = 0
Do
C = (Asc(Mid(ActiveCell, (S - x), 1)) - 64) * (26 ^ x) + C
x = x + 1
Loop Until x = S
ActiveCell.Offset(0, 1) = C
ActiveCell.Offset(1, 0).Activate
Loop Until ActiveCell = ""
End Sub
Utilise la colonne A pour l'entrée, les sorties vers la colonne B, s'exécute un VB clic sur le bouton de commande. = D
Groovy: 51 caractères
char[] a=args[0];t=0;for(i in a)t=26*t+i-64;print t
Appeler en tant que
groovy *scriptname* ROFL
ou
groovy -e "char[] a=args[0];t=0;for(i in a)t=26*t+i-64;print t" ROFL
C'est essentiellement la même chose que Java. J'imagine quelques possibilités avec l'utilisation des plages et des fermetures, mais rien ne me vient à l'esprit pour cet exemple. Quelqu'un d'autre voit un moyen de raccourcir cela?
Une version plus groovy avec une fermeture est un peu plus longue, malheureusement.
t=0;args[0].toCharArray().each{t=t*26+it-64};print t