web-dev-qa-db-fra.com

Convertir une chaîne en code Morse

Le défi

Le code le plus court par nombre de caractères, qui entrera une chaîne en utilisant uniquement des caractères alphabétiques (majuscules et minuscules), des chiffres, des virgules, des points et un point d'interrogation, et renvoie une représentation de la chaîne en code Morse. La sortie du code Morse doit consister en un tiret (-, ASCII 0x2D) pour un bip long (AKA 'dah') et un point (., ASCII 0x2E) pour un bip court (AKA 'dit').

Chaque lettre doit être séparée par un espace (' ', ASCII 0x20), et chaque mot doit être séparé par une barre oblique (/, ASCII 0x2F).

Table de code Morse:

texte alternatif http://liranuna.com/junk/morse.gif

Cas de test:

Input:
    Hello world

Output:
    .... . .-.. .-.. --- / .-- --- .-. .-.. -..

Input:
    Hello, Stackoverflow.

Output:
    .... . .-.. .-.. --- --..-- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- .-.-.-

Le nombre de codes comprend les entrées/sorties (c'est-à-dire le programme complet).

57
LiraNuna

C (131 characters)

Oui, 131!

main(c){for(;c=c?c:(c=toupper(getch())-32)?
"•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-12]-34:-3;c/=2)putch(c/2?46-c%2:0);}

J'ai effleuré quelques caractères supplémentaires en combinant la logique des boucles while et for en une seule boucle for, et en déplaçant la déclaration de c variable dans la définition main comme paramètre d'entrée. Cette dernière technique que j'ai empruntée à la réponse de Strager à un autre défi .


Pour ceux qui essaient de vérifier le programme avec GCC ou avec des éditeurs ASCII uniquement, vous aurez peut-être besoin de la version suivante, légèrement plus longue:

main(c){for(;c=c?c:(c=toupper(getchar())-32)?c<0?1:
"\x95#\x8CKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-12]-34:-3;c/=2)putchar(c/2?46-c%2:32);}

Cette version est plus longue de 17 caractères (pesant 148), en raison des modifications suivantes:

  • +4: getchar() et putchar() au lieu du non portable getch() et putch()
  • +6: codes d'échappement pour deux des caractères au lieu des caractères non ASCII
  • +1: 32 au lieu de 0 pour le caractère espace
  • +6: ajout de "c<0?1:" Pour supprimer les ordures des caractères inférieurs à ASCII 32 (à savoir, de '\n'). Vous obtiendrez toujours les ordures de tout de !"#$%&'()*+[\]^_ `{|}~, ou n'importe quoi au-dessus ASCII 126.

Cela devrait rendre le code complètement portable. Compiler avec:

gcc -std = c89 -funsigned-char morse.c

Le -std=c89 Est facultatif. Le -funsigned-char Est cependant nécessaire, sinon vous obtiendrez des ordures pour la virgule et le point final.


135 caractères

c;main(){while(c=toupper(getch()))for(c=c-32?
"•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-44]-34:-3;c;c/=2)putch(c/2?46-c%2:0);}

À mon avis, cette dernière version est également beaucoup plus attrayante visuellement. Et non, ce n'est pas portable et il n'est plus protégé contre les entrées en dehors des limites. Il a également une interface utilisateur assez mauvaise, prenant une entrée caractère par caractère et la convertissant en code Morse et ayant une condition de sortie non (vous devez appuyer sur Ctrl+Break). Mais un code portable et robuste avec une belle interface utilisateur n'était pas une exigence.

Une explication aussi brève que possible du code suit:

main(c){
    while(c = toupper(getch())) /* well, *sort of* an exit condition */
        for(c =
            c - 32 ? // effectively: "if not space character"
            "•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"[c - 44] - 34
            /* This array contains a binary representation of the Morse Code
             * for all characters between comma (ASCII 44) and capital Z.
             * The values are offset by 34 to make them all representable
             * without escape codes (as long as chars > 127 are allowed).
             * See explanation after code for encoding format.
             */
            : -3; /* if input char is space, c = -3
                   * this is chosen because -3 % 2 = -1 (and 46 - -1 = 47)
                   * and -3 / 2 / 2 = 0 (with integer truncation)
                   */
            c; /* continue loop while c != 0 */
            c /= 2) /* shift down to the next bit */
                putch(c / 2 ? /* this will be 0 if we're down to our guard bit */
                    46 - c % 2 /* We'll end up with 45 (-), 46 (.), or 47 (/).
                                * It's very convenient that the three characters
                                * we need for this exercise are all consecutive.
                                */
                    : 0 /* we're at the guard bit, output blank space */
                );
}

Chaque caractère de la longue chaîne du code contient le code Morse codé pour un caractère de texte. Chaque bit du caractère codé représente soit un tiret soit un point. Un représente un tiret et un zéro représente un point. Le bit le moins significatif représente le premier tiret ou point du code Morse. Un bit "garde" final détermine la longueur du code. C'est-à-dire que le bit le plus élevé de chaque caractère codé représente la fin du code et n'est pas imprimé. Sans ce bit de garde, les caractères avec des points de fin ne pourraient pas être imprimés correctement.

Par exemple, la lettre "L" est ".-.." Dans le code Morse. Pour représenter cela en binaire, nous avons besoin d'un 0, d'un 1 et de deux autres 0, en commençant par le bit le moins significatif: 0010. Tack un 1 de plus pour un bit de garde, et nous avons notre code Morse codé: 10010, ou décimal 18. Ajoutez le décalage +34 pour obtenir 52, qui est la valeur ASCII du caractère "4". Ainsi, le tableau de caractères codés a un "4" comme 33ème caractère (index 32) .

Cette technique est similaire à celle utilisée pour coder les caractères dans ACoolie's , strager's(2), Miles's , pingw33n's , Alec's , et Andrea's solutions, mais est légèrement plus simple, ne nécessitant qu'une seule opération par bit (décalage/division), plutôt que deux (décalage/division et décrémentation).

MODIFIER:
En lisant le reste des implémentations, je vois que Alec et Anon est venu avec ce schéma de codage — en utilisant le bit de garde — avant moi. La solution d'Anon est particulièrement intéressante, en utilisant la fonction bin de Python et en supprimant le préfixe "0b" Et le bit de garde avec [3:], Plutôt que de boucler, anding et décalage, comme Alec et J'ai fait.

En prime, cette version gère également les tirets (-....-), Les barres obliques (-..-.), Les deux points (---...), Les points-virgules (-.-.-.), Égaux ( -...-), Et au signe (.--.-.). Tant que les caractères 8 bits sont autorisés, ces caractères ne nécessitent aucun octet de code supplémentaire à prendre en charge. Aucun autre caractère ne peut être pris en charge avec cette version sans ajouter de longueur au code (sauf s'il y a des codes Morse pour plus/moins de signes).

Parce que je trouve les anciennes implémentations toujours intéressantes et que le texte contient quelques mises en garde applicables à cette version, j'ai laissé le contenu précédent de ce post ci-dessous.


D'accord, sans doute, l'interface utilisateur peut être nulle, non? Donc, en empruntant à strager , j'ai remplacé gets(), qui fournit une entrée de ligne en tampon et en écho, par getch(), qui fournit une entrée de caractère sans tampon et sans écho. Cela signifie que chaque caractère que vous tapez est immédiatement traduit en Morse Code à l'écran. C'est peut-être cool. Cela ne fonctionne plus avec stdin ou un argument de ligne de commande, mais c'est sacrément petit.

J'ai cependant gardé l'ancien code ci-dessous pour référence. Voici le nouveau.

Nouveau code, avec vérification des limites, 171 caractères:

W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13)
c=c-19?c>77|c<31?0:W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"
[c-31]-42):putch(47),putch(0);}

Enter rompt la boucle et quitte le programme.

Nouveau code, sans vérification des limites, 159 caractères:

W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13)
c=c-19?W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-31]-42):
putch(47),putch(0);}

Ci-dessous suit l'ancien code 196/177, avec quelques explications:

W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,c,s[99];gets(s);
for(p=s;*p;)c=*p++,c=toupper(c),c=c-32?c>90|c<44?0:W(
"œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-44]-42):
putch(47),putch(0);}

Ceci est basé sur Andrea Python , en utilisant la même technique pour générer le code morse que dans cette réponse. Mais au lieu de stocker les caractères encodables les uns après les autres et de trouver leurs index, j'ai stocké les index les uns après les autres et les recherche par caractère (de la même manière que ma réponse précédente ). Cela évite les longues lacunes près de la fin qui ont causé des problèmes aux implémenteurs antérieurs.

Comme avant , j'ai utilisé un caractère supérieur à 127. Le convertir en ASCII ajoute seulement 3 caractères. Le premier caractère de la longue chaîne doit être remplacé par \x9C. Le décalage est nécessaire cette fois, sinon un grand nombre de caractères est inférieur à 32, et doit être représenté avec des codes d'échappement.

Comme précédemment, le traitement d'un argument de ligne de commande au lieu de stdin ajoute 2 caractères et l'utilisation d'un véritable espace entre les codes ajoute 1 caractère.

D'un autre côté, certaines des autres routines ici ne traitent pas des entrées en dehors de la plage acceptée de [ .0-9 \? A-Za-z]. Si une telle manipulation était supprimée de cette routine, alors 19 caractères pourraient être supprimés, ce qui ramènerait le total à 177 caractères. Mais si cela est fait et qu'une entrée non valide est envoyée à ce programme, il peut se bloquer et brûler.

Le code dans ce cas pourrait être:

W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,s[99];gets(s);
for(p=s;*p;p++)*p=*p-32?W(
"œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"
[toupper(*p)-44]-42):putch(47),putch(0);}
70
P Daddy

Utilisation d'une police de code Morse ?

Console.Write(params[0]);
48
johnc

Perl, 170 caractères (avec l'aide d'un golfeur accompli mauke). Enveloppé pour plus de clarté; toutes les nouvelles lignes sont amovibles.

$_=uc<>;y,. ,|/,;s/./$& /g;@m{A..Z,0..9,qw(| , ?)}=
".-NINNN..]IN-NII..AMN-AI---.M-ANMAA.I.-].AIAA-NANMMIOMAOUMSMSAH.B.MSOIONARZMIZ"
=~/../g;1while s![]\w|,?]!$m{$&}!;print

Explication:

  1. Extrayez le dictionnaire morse. Chaque symbole est défini en termes de deux caractères, qui peuvent être des points ou des tirets littéraux, ou une référence à la valeur d'un autre caractère défini. E et T contiennent des caractères factices pour éviter de désynchroniser le décodeur; nous les supprimerons plus tard.
  2. Lisez et formatez l'entrée. "Hello world" devient "H E L L O / W O R L D"
  3. L'étape suivante dépend des dictionnaires d'entrée et de sortie étant distincts, donc tournez les points dans l'entrée vers un caractère inutilisé (barre verticale, |)
  4. Remplacez tout caractère dans l'entrée qui se produit dans le dictionnaire morse par sa valeur dans le dictionnaire, jusqu'à ce qu'aucun remplacement ne se produise.
  5. Retirez l'omble factice mentionné à l'étape 1.
  6. Imprimez la sortie.

Dans la version finale, le dictionnaire est optimisé pour l'efficacité d'exécution:

  • Tous les caractères à un symbole (E et T) et les caractères à deux symboles (A, I, M et N) sont définis directement et décodent en une seule passe.
  • Tous les caractères à trois symboles sont définis en termes de caractère à deux symboles et de symbole littéral, décodés en deux passes.
  • Tous les caractères à quatre symboles sont définis en termes de deux caractères à deux symboles, décodés en deux passes avec trois remplacements.
  • Les caractères à cinq et six symboles (chiffres et ponctuation) décodent en trois passes, avec quatre ou cinq remplacements respectivement.

Étant donné que le code joué ne remplace qu'un caractère par boucle (pour enregistrer un caractère de code!), Le nombre de boucles est limité à cinq fois la longueur de l'entrée (trois fois la longueur de l'entrée si seuls les caractères alphabétiques sont utilisés). Mais en ajoutant un g au s/// opération, le nombre de boucles est limité à trois (deux si seuls les alphabétiques sont utilisés).

Exemple de transformation:

Hello 123
H E L L O / 1 2 3
II .] AI AI M- / AO UM SM
.... . .-.. .-.. --- / .-M- .A-- I.--
.... . .-.. .-.. --- / .---- ..--- ...--
23
hobbs

Compréhension de la liste Python, ligne unique de 159 caractères

for c in raw_input().upper():print c<","and"/"or bin(ord("•ƒwTaQIECBRZ^`šŒ#S#n|':<.$402&9/6)(18?,*%+3-;=>"[ord(c)-44])-34)[3:].translate(" "*47+"/.-"+" "*206),

Utilise la compression de données similaire à implémentation C de P Daddy , mais ne stocke pas les bits dans l'ordre inverse et utilise bin() pour extraire les données plutôt que l'arithmétique. Notez également que les espaces sont détectés en utilisant l'inégalité; il considère que chaque caractère "moins qu'une virgule" est un espace.

Boucle Python for, 205 caractères, y compris les sauts de ligne

for a in raw_input().upper():
 q='_ETIANMSURWDKGOHVF_L_PJBXCYZQ__54_3___2__+____16=/_____7___8_90'.find(a);s=''
 while q>0:s='-.'[q%2]+s;q=~-q/2
 print['/','--..--','..--..','.-.-.-',''][' ,?.'.find(a)]+s,
16
ACoolie

Je travaillais avec un codage compact pour les symboles, mais je ne vois pas si cela va mieux que les arbres implicites déjà utilisés, donc je présente le codage ici au cas où quelqu'un d'autre pourrait l'utiliser.

Considérez la chaîne:

 --..--..-.-.-..--...----.....-----.--/

qui contient toutes les séquences nécessaires en tant que sous-chaînes. Nous pourrions coder les symboles par décalage et longueur comme ceci:

       ET  RRRIIGGGJJJJ    
--..--..-.-.-..--...----.....-----.--/
          CCCC  DD WWW       00000
,,,,,,   AALLLL BBBB        11111
--..--..-.-.-..--...----.....-----.--/
  ??????  KKK  MMSSS       22222   
        FFFF  PPPP        33333
--..--..-.-.-..--...----.....-----.--/
        UUU XXXX         44444       
          NN  PPPP  OOO 55555
--..--..-.-.-..--...----.....-----.--/
               ZZZZ    66666
                      77777      YYYY
--..--..-.-.-..--...----.....-----.--/
       ......        88888 HHHH
                    99999 VVVV  QQQQ
--..--..-.-.-..--...----.....-----.--/

avec l'espace (c.-à-d. la limite du mot) commençant et se terminant par le dernier caractère (le '/'). N'hésitez pas à l'utiliser, si vous voyez un bon moyen.

La plupart des symboles plus courts ont bien sûr plusieurs codages possibles.


P Daddy a trouvé une version plus courte de cette astuce (et je peux maintenant voir au moins une partie de la redondance ici) et a fait une implémentation de Nice c. Alec a fait une python avec la première version (buggy et incomplète). Hobbs a fait une version Perl assez compacte que je ne fais pas comprendre du tout.

7
dmckee

J, 124 130134 personnages

'.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper

J bat C! Impressionnant!

Usage:

   '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper 'Hello World'
.... . .-.. .-.. --- / .-- --- .-. .-.. -.. 

   '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper 'Hello, Stackoverflow.'
.... . .-.. .-.. --- .-.-.- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- --..-- 
6
David

Golfscript - 106 caractères - PAS DE CHARS DRÔLES :)

la nouvelle ligne à la fin de l'entrée n'est pas prise en charge, utilisez donc quelque chose comme ceci

echo -n Hello, Stackoverflow| ../golfscript.rb morse.gs

' '/{{.32|"!etianmsurwdkgohvf!l!pjbxcyzq"?)"UsL?/'#! 08<>"@".,?0123456789"?=or
2base(;>{'.-'\=}%' '}%}%'/'*

Les lettres sont un cas spécial et converties en minuscules et ordonnées dans leurs positions binaires.
Tout le reste est fait par une table de traduction

5
John La Rooy

Caractères C # 266

La solution de 131 caractères C traduite en C # produit 266 caractères:

foreach(var i in Encoding.ASCII.GetBytes(args[0].ToUpper())){var c=(int)i;for(c=(c-32!=0)?Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c-44]-34:-3;c!=0;c/=2)Console.Write(Encoding.ASCII.GetChars(new byte[]{(byte)((c/2!=0)?46-c%2:0)}));}

qui est plus lisible comme:

foreach (var i in Encoding.ASCII.GetBytes(args[0].ToUpper()))
{
    var c = (int)i;
    for (c = ((c - 32) != 0) ? Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c - 44] - 34 : -3
        ; c != 0
        ; c /= 2)
        Console.Write(Encoding.ASCII.GetChars(new byte[] { (byte)((c / 2 != 0) ? 46 - c % 2 : 0) }));
}
5
Jader Dias

Python 3 One Liner: 172 caractères

print(' '.join('/'if c==' 'else''.join('.'if x=='0'else'-'for x in bin(ord("ijÁĕÁÿïçãáàðøüþÁÁÁÁÁČÁÅ×ÚÌÂÒÎÐÄ×ÍÔÇÆÏÖÝÊÈÃÉÑËÙÛÜ"[ord(c)-44])-192)[3:])for c in input().upper()))

(Encodage de la table de traduction en points de code unicode. Fonctionne très bien, et ils s'affichent bien ici dans mon test sur ma machine Windows Vista.)

Modifié pour réduire à 184 caractères en supprimant certains espaces et crochets inutiles (création d'expositions génériques de la liste).

Modifier à nouveau: Plus d'espace supprimé que je ne savais même pas possible avant de voir d'autres réponses ici - donc jusqu'à 176.

Modifiez à nouveau jusqu'à 172 (woo woo!) En utilisant '' .join au lieu de '' .join et en faisant les espaces séparément. (duh!)

5
Anon

Python

Solution incomplète, mais peut-être que quelqu'un peut en faire une solution complète. Ne gère pas les chiffres ou la ponctuation, mais ne pèse que 154 caractères.

def e(l):
 i='_etianmsurwdkgohvf_l_pjbxcyzq'.find(l.lower());v=''
 while i>0:v='-.'[i%2]+v;i=(i-1)/2;return v or '/'
def enc(s):return ' '.join(map(e,s))
4
Alec

C (248 characters)

Une autre solution arborescente.

#define O putchar
char z[99],*t=
" ETINAMSDRGUKWOHBL~FCPJVX~YZQ~~54~3~~~2~~+~~~~16=/~~.~~7,~~8~90";c,p,i=0;
main(){gets(z);while(c=z[i++]){c-46?c-44?c:O(45):O(c);c=c>96?c-32:c;p=-1;
while(t[++p]!=c);for(;p;p/=2){O(45+p--%2);}c-32?O(32):(O(47),O(c));}}

Il pourrait y avoir des erreurs dans l'arborescence source parce que wikipedia semble avoir mal ou peut-être que j'ai mal compris quelque chose.

3
pingw33n

F #, 256 caractères

let rec D i=if i=16 then" "else
 let x=int"U*:+F8c]uWjGbJ0-0Dnmd0BiC5?\4o`h7f>9[1E=pr_".[i]-32
 if x>43 then"-"+D(x-43)else"."+D x
let M(s:string)=s.ToUpper()|>Seq.fold(fun s c->s+match c with
|' '->"/ "|','->"--..-- "|'.'->".-.-.- "|_->D(int c-48))""

Par exemple

M("Hello, Stack.") |> printfn "%s"

les rendements

.... . .-.. .-.. --- --..-- / ... - .- -.-. -.- .-.-.-

Je pense que ma technique peut être unique jusqu'à présent. L'idée est:

  • il y a une gamme ascii de caractères qui couvre la plupart de ce que nous voulons (0..Z)
  • il n'y a que 43 caractères dans cette gamme
  • nous pouvons donc encoder un bit (tiret ou point) plus un "caractère suivant" dans une plage de 86 caractères
  • la gamme ascii (32-117) est entièrement imprimable et peut servir de gamme de 86 caractères
  • de sorte que la chaîne littérale code pour une table dans ce sens

Il y a un peu plus, mais c'est l'essentiel. La virgule, le point et l'espace ne sont pas compris entre 0 et Z, ils sont donc traités spécialement par la "correspondance". Certains caractères "inutilisés" dans la plage 0..Z (comme ";") sont utilisés dans le tableau comme suffixes d'autres traductions morse qui ne sont pas elles-mêmes des "lettres" morse.

3
Brian

REBOL (118 caractères)

Une implémentation vieille d'environ 10 ans

foreach c ask""[l: index? find" etinamsdrgukwohblzfcpövxäqüyj"c while[l >= 2][prin pick"-."odd? l l: l / 2]prin" "]

Cité de: http://www.rebol.com/oneliners.html

(pas de chiffres cependant et les mots sont juste séparés par des doubles espaces:/...)

3
onetom

Voici ma contribution en tant qu'application console dans VB.Net

Module MorseCodeConverter

    Dim M() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."}

    Sub Main()
        Dim I, O
        Dim a, b

        While True
            I = Console.ReadLine()
            O = ""

            For Each a In I
                b = AscW(UCase(a))
                If b > 64 And b < 91 Then
                    O &= M(b - 65) & " "
                ElseIf b > 47 And b < 58 Then
                    O &= M(b - 22) & " "
                ElseIf b = 46 Then
                    O &= ".-.-.- "
                ElseIf b = 44 Then
                    O &= "--..-- "
                ElseIf b = 63 Then
                    O &= "..--.. "
                Else
                    O &= "/"
                End If

            Next

            Console.WriteLine(O)
        End While


    End Sub

End Module

J'ai laissé un espace blanc pour le rendre lisible. Totaux 1100 caractères. Il lira l'entrée de la ligne de commande, une ligne à la fois, et renverra la sortie correspondante au flux de sortie. La version compressée est ci-dessous, avec seulement 632 caractères.

Module Q
    Dim M() As String={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."}
    Sub Main()
        Dim I,O,a,b:While 1:I=Console.ReadLine():O="":For Each a In I:b=AscW(UCase(a)):If b>64 And b<91 Then:O &=M(b-65)&" ":ElseIf b>47 And b<58 Then:O &=M(b-22)&" ":ElseIf b=46 Then:O &=".-.-.- ":ElseIf b=44 Then:O &="--..-- ":ElseIf b=63 Then:O &= "..--.. ":Else:O &="/":End IF:Next:Console.WriteLine(O):End While
    End Sub
End Module
3
Kibbee

C (233 characters)

W(n,p){while(n--)putch(".-.-.--.--..--..-.....-----..../"[p++]);}main(){
char*p,c,s[99];gets(s);for(p=s;*p;){c=*p++;c=toupper(c);c=c>90?35:c-32?
"È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ"[c-44]:63;c-35?
W(c>>5,c&31):0;putch(0);}}

Cela prend l'entrée de stdin. La saisie de la ligne de commande ajoute 2 caractères. Au lieu de:

...main(){char*p,c,s[99];gets(s);for(p=s;...

vous obtenez:

...main(int i,char**s){char*p,c;for(p=s[1];...

J'utilise la page de codes Windows-1252 pour les caractères supérieurs à 127, et je ne sais pas comment ils apparaîtront dans les navigateurs d'autres personnes. Je remarque que, dans mon navigateur au moins (Google Chrome), deux des caractères (entre "@" et "i") n'apparaissent pas. Si vous copiez hors du navigateur et collez dans un éditeur de texte, cependant, ils apparaissent, bien que sous forme de petites boîtes.

Il peut être converti en ASCII uniquement, mais cela ajoute 24 caractères, augmentant le nombre de caractères à 257. Pour ce faire, je décale d'abord chaque caractère de la chaîne de -64, minimisant le nombre de caractères supérieurs à 127. Ensuite Je remplace \x [~ # ~] xx [~ # ~] le caractère s'échappe si nécessaire. Cela change cela:

...c>90?35:c-32?"È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ"[c-44]:63;
c-35?W(...

pour ça:

...c>90?99:c-32?"\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1
\xE1*S$ICH"[c-44]+64:63;c-99?W(...

Voici une version plus joliment formatée et commentée du code:

/* writes `n` characters from internal string to stdout, starting with
 * index `p` */
W(n,p){
    while(n--)
        /* warning for using putch without declaring it */
        putch(".-.-.--.--..--..-.....-----..../"[p++]);

        /* dmckee noticed (http://tinyurl.com/n4eart) the overlap of the
         * various morse codes and created a 37-character-length string that
         * contained the morse code for every required character (except for
         * space).  You just have to know the start index and length of each
         * one.  With the same idea, I came up with this 32-character-length
         * string.  This not only saves 5 characters here, but means that I
         * can encode the start indexes with only 5 bits below.
         *
         * The start and length of each character are as follows:
         *
         *   A:  0,2    K:  1,3    U: 10,3    4: 18,5
         *   B: 16,4    L: 15,4    V: 19,4    5: 17,5
         *   C:  1,4    M:  5,2    W:  4,3    6: 16,5
         *   D:  9,3    N:  1,2    X:  9,4    7: 25,5
         *   E:  0,1    O: 22,3    Y:  3,4    8: 24,5
         *   F: 14,4    P:  4,4    Z:  8,4    9: 23,5
         *   G:  5,3    Q:  5,4    0: 22,5    .:  0,6
         *   H: 17,4    R:  0,3    1: 21,5    ,:  8,6
         *   I: 20,2    S: 17,3    2: 20,5    ?: 10,6
         *   J: 21,4    T:  1,1    3: 19,5
         */
}

main(){ /* yuck, but it compiles and runs */
    char *p, c, s[99];
    /* p is a pointer within the input string */
    /* c saves from having to do `*p` all the time */
    /* s is the buffer for the input string */

    gets(s); /* warning for use without declaring */

    for(p=s; *p;){ /* begin with start of input, go till null character */
        c = *p++; /* grab *p into c, increment p.
                   * incrementing p here instead of in the for loop saves
                   * one character */

        c=toupper(c); /* warning for use without declaring */

        c = c > 90 ? 35 : c - 32 ?
            "È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ"[c - 44] : 63;

        /**** OR, for the ASCII version ****/

        c = c > 90 ? 99 : c - 32 ?
           "\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1\xE1"
           "*S$ICH"[c - 44] + 64 : 63;

        /* Here's where it gets hairy.
         *
         * What I've done is encode the (start,length) values listed in the
         * comment in the W function into one byte per character.  The start
         * index is encoded in the low 5 bits, and the length is encoded in
         * the high 3 bits, so encoded_char = (char)(length << 5 | position).
         * For the longer, ASCII-only version, 64 is subtracted from the
         * encoded byte to reduce the necessity of costly \xXX representations.
         * 
         * The character array includes encoded bytes covering the entire range
         * of characters covered by the challenge, except for the space
         * character, which is checked for separately.  The covered range
         * starts with comma, and ends with capital Z (the call to `toupper`
         * above handles lowercase letters).  Any characters not supported are
         * represented by the "#" character, which is otherwise unused and is
         * explicitly checked for later.  Additionally, an explicit check is
         * done here for any character above 'Z', which is changed to the
         * equivalent of a "#" character.
         * 
         * The encoded byte is retrieved from this array using the value of
         * the current character minus 44 (since the first supported character
         * is ASCII 44 and index 0 in the array).  Finally, for the ASCII-only
         * version, the offset of 64 is added back in.
         */

        c - 35 ? W(c >> 5, c & 31) : 0;

        /**** OR, for the ASCII version ****/

        c - 99 ? W(c >> 5, c & 31) : 0;

        /* Here's that explicit check for the "#" character, which, as
         * mentioned above, is for characters which will be ignored, because
         * they aren't supported.  If c is 35 (or 99 for the ASCII version),
         * then the expression before the ? evaluates to 0, or false, so the
         * expression after the : is evaluated.  Otherwise, the expression
         * before the ? is non-zero, thus true, so the expression before
         * the : is evaluated.
         *
         * This is equivalent to:
         *
         *     if(c != 35) // or 99, for the ASCII version
         *         W(c >> 5, c & 31);
         *
         * but is shorter by 2 characters.
         */

        putch(0);
        /* This will output to the screen a blank space.  Technically, it's not
         * the same as a space character, but it looks like one, so I think I
         * can get away with it.  If a real space character is desired, this
         * must be changed to `putch(32);`, which adds one character to the
         * overall length.
    } /* end for loop, continue with the rest of the input string */
} /* end main */

Cela bat tout ici, sauf pour quelques implémentations Python. Je continue de penser que cela ne peut pas être plus court, mais je trouve un moyen de raser quelques caractères supplémentaires. Si quelqu'un peut trouver plus de place pour l'amélioration, faites le moi savoir.

MODIFIER:

J'ai remarqué que, bien que cette routine rejette tous les caractères non valides ci-dessus ASCII 44 (sortie juste un espace vide pour chacun), elle ne vérifie pas les caractères non valides en dessous de cette valeur. Pour les vérifier ajoute 5 caractères à la longueur totale, en changeant ceci:

...c>90?35:c-32?"...

pour ça:

...c-32?c>90|c<44?35:"...
3
P Daddy

Python 2; 171 caractères

Fondamentalement la même chose que la solution d'Andrea , mais en tant que programme complet, et en utilisant des astuces stupides pour le raccourcir.

for c in raw_input().lower():print"".join(".-"[int(d)]for d in bin(
('  etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'
%(('',)*5)).find(c))[3:])or'/',

(les nouvelles lignes ajoutées peuvent toutes être supprimées)

Ou, si vous préférez ne pas utiliser la fonction bin() en 2.6, nous pouvons le faire en 176:

for c in raw_input():C=lambda q:q>0and C(~-q/2)+'-.'[q%2]or'';print C(
(' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'%
(('',)*5)).find(c.lower()))or'/',

(encore une fois, les nouvelles lignes ajoutées peuvent toutes être supprimées)

2
Miles

C, 338 caractères

338 avec retrait et tous les sauts de ligne amovibles supprimés:

#define O putchar
#define W while
char*l="x@@@@@ppmmmmm@@FBdYcbcbSd[Kcd`\31(\b1g_<qCN:_'|\25D$W[QH0";
int c,b,o;
main(){
  W(1){
    W(c<32)
      c=getchar()&127;
    W(c>96)
      c^=32;
    c-=32;
    o=l[c/2]-64;
    b=203+(c&1?o>>3:0);
    o=c&1?o&7:o>>3;
    W(o>6)
      O(47),o=0;
    c/=2;
    W(c--)
      b+=(l[c]-64&7)+(l[c]-64>>3);
    b=(((l[b/7]<<7)+l[b/7+1])<<(b%7))>>14-o;
    W(o--)
      O(b&(1<<o)?46:45);
    O(32);
  }
}

Ce n'est pas basé sur l'approche arborescente que d'autres personnes ont adoptée. Au lieu de cela, l code d'abord les longueurs de tous les octets compris entre 32 et 95 inclus, deux octets pour un caractère. Par exemple, D est - .. pour une longueur de 3 et E est. pour une longueur de 1. Ceci est codé comme 011 et 001, donnant 011001. Pour rendre plus de caractères encodables et éviter les échappements, 64 est ensuite ajouté au total, donnant 1011001 - 89, ASCII Y Les caractères non morse se voient attribuer une longueur de 0. La seconde moitié de l (commençant par \031) sont les bits du code morse lui-même, avec un point égal à 1 et un tiret 0. Pour éviter d'entrer en ASCII élevé, ces données sont codées à 7 bits/octet.

Le code nettoie d'abord c, puis calcule la longueur morse de c (dans o), puis additionne les longueurs de tous les caractères précédents pour produire b, l'index des bits dans les données.

Enfin, il parcourt les bits, imprimant des points et des tirets.

La longueur "7" est utilisée comme indicateur spécial pour imprimer un/lorsque vous rencontrez un espace.

Il y a probablement quelques petits gains à retirer de la suppression des crochets, mais je suis loin de certains des meilleurs résultats et j'ai faim, alors ...

2
Jon Bright

C # en utilisant Linq (133 caractères)

    static void Main()
    {
        Console.WriteLine(String.Join(" ", (from c in Console.ReadLine().ToUpper().ToCharArray()
                                            select m[c]).ToArray()));
    }

OK, j'ai donc triché. Vous devez également définir un dictionnaire comme suit (cela n'a pas pris la peine de compter les caractères, car cela me souffle hors du jeu):

    static Dictionary<char, string> m = new Dictionary<char, string>() {
            {'A', ".-"},
            {'B', "-.."},
            {'C', "-.-."},
            {'D', "-.."},
            {'E', "."},
            {'F', "..-."},
            {'G', "--."},
            {'H', "...."},
            {'I', ".."},
            {'J', ".---"},
            {'K', "-.-"},
            {'L', ".-.."},
            {'M', "--"},
            {'N', "-."},
            {'O', "---"},
            {'P', ".--."},
            {'Q', "--.-"},
            {'R', ".-."},
            {'S', "..."},
            {'T', "-"},
            {'U', "..-"},
            {'V', "...-"},
            {'W', ".--"},
            {'X', "-..-"},
            {'Y', "-.--"},
            {'Z', "--.."},
            {'0', "-----"},
            {'1', ".----"},
            {'2', "..---"},
            {'3', "...--"},
            {'4', "....-"},
            {'5', "....."},
            {'6', "-...."},
            {'7', "--..."},
            {'8', "---.."},
            {'9', "----."},
            {' ', "/"},
            {'.', ".-.-.-"},
            {',', "--..--"},
            {'?', "..--.."},
        };

Pourtant, quelqu'un peut-il fournir une implémentation C # plus concise qui est également aussi facile à comprendre et à maintenir que cela?

2
DSO

Perl, 206 caractères, en utilisant l'idée de dmckee

C'est plus long que le premier que j'ai soumis, mais je pense toujours que c'est intéressant . Et/ou horrible. Je ne suis pas encore sûr. Cela utilise l'idée de codage de dmckee, ainsi que quelques autres bonnes idées que j'ai vues. Au début, je pensais que la chose "longueur/décalage dans une chaîne fixe" ne pouvait pas produire moins de données que le schéma de mon autre solution, qui utilise deux octets fixes par caractère (et tous les octets imprimables, à ce sujet). J'ai en fait réussi à réduire considérablement les données (un octet par caractère, plus quatre octets pour stocker le modèle de 26 bits dans lequel nous indexons), mais le code pour le récupérer est plus long, malgré mes meilleurs efforts pour jouer au golf. (Moins complexe, OMI, mais plus long quand même).

Quoi qu'il en soit, 206 caractères; les nouvelles lignes sont amovibles sauf la première.

#!Perl -lp
($a,@b)=unpack"b32C*",
"\264\202\317\0\31SF1\2I.T\33N/G\27\308XE0=\x002V7HMRfermlkjihgx\207\205";
$a=~y/01/-./;@m{A..Z,0..9,qw(. , ?)}=map{substr$a,$_%23,1+$_/23}@b;
$_=join' ',map$m{uc$_}||"/",/./g

Explication:

  • Les données comportent deux parties. Les quatre premiers octets ("\264\202\317\0") représentent 32 bits de code morse ("--.-..-.-.-----.....--..--------") bien que seuls les 26 premiers bits soient utilisés. Il s'agit de la "chaîne de référence".
  • Le reste de la chaîne de données stocke la position de départ et la longueur des sous-chaînes de la chaîne de référence qui représentent chaque caractère - un octet par caractère, dans l'ordre (A, B, ... Z, 0, 1, ... 9 , ".", ",", "?"). Les valeurs sont codées 23 * (longueur - 1) + pos, et le décodeur inverse cela. Le dernier point de départ est bien sûr 22.
  • Ainsi, le déballage fait la moitié du travail d'extraction des données et la troisième ligne (comme vu ici) fait le reste, maintenant nous avons un hachage avec $m{'a'} = '.-' et cetera, il ne reste plus qu'à faire correspondre les caractères de l'entrée, à les rechercher dans le hachage et à formater la sortie, ce que fait la dernière ligne ... avec l'aide du Shebang, qui dit à Perl de supprimer la nouvelle ligne en entrée, placez les lignes d'entrée dans $_, et lorsque le code est terminé, écrivez $_ retour à la sortie avec ajout de nouvelles lignes.
2
hobbs

Python (210 caractères)

Ceci est une solution complète basée sur celle de Alec

def e(l):
 i=(' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'%Tuple('_'*5)).find(l.lower());v=''
 while i>0:v='-.'[i%2]+v;i=(i-1)/2
 return v or '/'
def enc(s):return ' '.join(map(e,s))
2
Andrea Ambu

PHP

J'ai modifié le précédent PHP entry pour être légèrement plus efficace. :)

$a=array(32=>"/",44=>"--..--",1,".-.-.-",48=>"-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",63=>"..--..",1,".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..");
foreach(str_split(strtoupper("hello world?"))as$k=>$v){echo $a[ord($v)]." ";}

Komodo dit 380 caractères sur 2 lignes - la ligne supplémentaire est juste pour la lisibilité. ; D Le 1 intercalé dans le tableau est juste pour enregistrer 2 octets en remplissant cette position du tableau avec des données au lieu de sauter manuellement à la position du tableau après cela.

Considérez le premier contre le second. La différence est clairement visible. :)

array(20=>"data",22=>"more data";
array(20=>"data",1,"more data";

Le résultat final, cependant, est exactement aussi long que vous utilisez les positions du tableau plutôt que de parcourir le contenu, ce que nous ne faisons pas sur ce parcours de golf.

Résultat final: 578 caractères, jusqu'à 380 (198 caractères, soit ~ 34,26% d'économies).

1
grimman

Bash, un script que j'ai écrit il y a quelque temps (l'horodatage dit l'année dernière) pesant 1661 caractères. Juste pour le plaisir vraiment :)

#!/bin/sh
txt=''
res=''
if [ "$1" == '' ]; then
    read -se txt
else
    txt="$1"
fi;
len=$(echo "$txt" | wc -c)
k=1
while [ "$k" -lt "$len" ]; do
    case "$(expr substr "$txt" $k 1 | tr '[:upper:]' '[:lower:]')" in
        'e')    res="$res"'.' ;;
        't')    res="$res"'-' ;;
        'i')    res="$res"'..' ;;
        'a')    res="$res"'.-' ;;
        'n')    res="$res"'-.' ;;
        'm')    res="$res"'--' ;;
        's')    res="$res"'...' ;;
        'u')    res="$res"'..-' ;;
        'r')    res="$res"'.-.' ;;
        'w')    res="$res"'.--' ;;
        'd')    res="$res"'-..' ;;
        'k')    res="$res"'-.-' ;;
        'g')    res="$res"'--.' ;;
        'o')    res="$res"'---' ;;
        'h')    res="$res"'....' ;;
        'v')    res="$res"'...-' ;;
        'f')    res="$res"'..-.' ;;
        'l')    res="$res"'.-..' ;;
        'p')    res="$res"'.--.' ;;
        'j')    res="$res"'.---' ;;
        'b')    res="$res"'-...' ;;
        'x')    res="$res"'-..-' ;;
        'c')    res="$res"'-.-.' ;;
        'y')    res="$res"'-.--' ;;
        'z')    res="$res"'--..' ;;
        'q')    res="$res"'--.-' ;;
        '5')    res="$res"'.....' ;;
        '4')    res="$res"'....-' ;;
        '3')    res="$res"'...--' ;;
        '2')    res="$res"'..---' ;;
        '1')    res="$res"'.----' ;;
        '6')    res="$res"'-....' ;;
        '7')    res="$res"'--...' ;;
        '8')    res="$res"'---..' ;;
        '9')    res="$res"'----.' ;;
        '0')    res="$res"'-----' ;;
    esac;
    [ ! "$(expr substr "$txt" $k 1)" == " " ] && [ ! "$(expr substr "$txt" $(($k+1)) 1)" == ' ' ] && res="$res"' '
    k=$(($k+1))
done;
echo "$res"
1
Hiato

Voici une troisième façon complètement différente d'encoder du code morse:

Python

232 caractères

def d(c):
 o='';b=ord("Y_j_?><80 !#'/_____f_\x06\x11\x15\x05\x02\x15\t\x1c\x06\x1e\r\x12\x07\x05\x0f\x16\x1b\n\x08\x03\r\x18\x0e\x19\x01\x13"[ord(c.upper())-44])
 while b!=1:o+='.-'[b&1];b/=2
 return o
e=lambda s:' '.join(map(d,s))

Si vous pouvez trouver un moyen de mapper cela sur un ensemble de caractères imprimables, vous pouvez enregistrer plusieurs caractères. C'est probablement ma solution la plus directe, même si je ne sais pas si c'est la plus lisible.

OK, maintenant j'ai perdu façon trop de temps à ce sujet.

1
Alec

C89 (293 caractères)

Basé sur certaines des autres réponses.

EDIT: rétréci l'arbre (oui).

#define P putchar
char t['~']="~ETIANMSURWDKGOHVF~L~PJBXCYZQ~~54~3",o,q[9],Q=10;main(c){for(;Q;)t[
"&./7;=>KTr"[--Q]]="2167890?.,"[Q];while((c=getchar())>=0){c-=c<'{'&c>96?32:0;c-
10?c-32?0:P(47):P(10);for(o=1;o<'~';++o)if(t[o]==c){for(;o;o/=2)q[Q++]=45+(o--&1
);for(;Q;P(q[--Q]));break;}P(32);}}
1
strager

Haskell

type MorseCode = String

program :: String
program = "__5__4H___3VS__F___2 UI__L__+_ R__P___1JWAE"
     ++ "__6__=B__/_XD__C__YKN__7_Z__QG__8_ __9__0 OMT "

decode :: MorseCode -> String
decode = interpret program
    where
    interpret         = head . foldl exec []
    exec xs       '_' = undefined : xs
    exec (x:y:xs)  c  = branch    : xs
        where
        branch (' ':ds) = c : decode ds
        branch ('-':ds) = x ds
        branch ('.':ds) = y ds
        branch []       = [c]

Par exemple, decode "-- --- .-. ... . -.-. --- -.. ." Retour "MORSE CODE".

Ce programme est tiré de l'excellent article Fun with Morse Code .

1
namin

Voici une autre approche, basée sur le travail de dmckee, démontrant à quel point lisible Python est:

Python

244 caractères

def h(l):p=2*ord(l.upper())-88;a,n=map(ord,"AF__GF__]E\\E[EZEYEXEWEVEUETE__________CF__IBPDJDPBGAHDPC[DNBSDJCKDOBJBTCND`DKCQCHAHCZDSCLD??OD"[p:p+2]);return "--..--..-.-.-..--...----.....-----.-"[a-64:a+n-128]
def e(s):return ' '.join(map(h,s))

Limites:

  • la chaîne de dmckee manquait le caractère 'Y', et j'étais trop paresseux pour l'ajouter. Je pense que tu devrais juste changer le "??" et ajoutez un "-" à la fin du deuxième littéral de chaîne
  • il ne met pas '/' entre les mots; encore une fois, paresseux

Étant donné que les règles exigeaient le moins caractères, pas le moins octets, vous pourriez réduire au moins l'une de mes tables de recherche (de moitié) si vous vouliez sortir de l'imprimable ASCII caractères.

EDIT: Si j'utilise des caractères Unicode choisis avec naïveté, mais que je les garde juste dans échappé ASCII dans le fichier source, il devient encore un peu plus court car le décodeur est plus simple:

Python

240 caractères

def h(l):a,n=divmod(ord(u'\x06_7_\xd0\xc9\xc2\xbb\xb4\xad\xa6\x9f\x98\x91_____\x14_AtJr2<s\xc1d\x89IQdH\x8ff\xe4Pz9;\xba\x88X_f'[ord(l.upper())-44]),7);return "--..--..-.-.-..--...----.....-----.-"[a:a+n]
def e(s):return ' '.join(map(h,s))

Je pense que cela clarifie également l'intention du programme.

Si vous avez enregistré cela en UTF-8, je pense que le programme compterait jusqu'à 185 caractères, ce qui en fait la solution complète la plus courte Python solution, et la deuxième seulement en Perl. :-)

1
Alec

C (381 characters)

char*p[36]={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
main(){int c;while((c=tolower(getchar()))!=10)printf("%s ",c==46?".-.-.-":c==44?"--..--":c==63?"..--..":c==32?"/":*(p+(c-97)));}
0
Andreas Grech

C , 448 octets utilisant des arguments cmdline:

char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*s,*p,x;main(int _,char**v){for(;s=*++v;putchar(10))for(;x=*s++;){p=strchr(k,x);printf("%s ",p?a[p-k]:isdigit(x)?a[x-18]:isalpha(x=toupper(x))?a[x-61]:0);}}

C , 416 octets utilisant stdin:

char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*p,x;main(){while((x=toupper(getchar()))-10){p=strchr(k,x);printf("%s ",p?a[p-k]:isdigit(x)?a[x-18]:isalpha(x)?a[x-61]:0);}}
0
Christoph

VBA/VB6 (576 caractères)

Remarque: aucune option explicite

Function MC(S)
For I = 1 To Len(S): C = UCase(Mid(S, I, 1)): MC = MC & IIf(C = " ", "/", "") & IIf(InStr("AEFHIJLPRSUVW12345.?", C), ".", IIf(InStr("BCDGKMNOQTXYZ06789,", C), "-", "")) & IIf(InStr("BCDFHIKNSUVXY23456?", C), ".", IIf(InStr("AGJLMOPQRWZ01789,.", C), "-", "")) & IIf(InStr("BDGHLQRSVXZ34567,.", C), ".", IIf(InStr("CFJKOPUWY01289?", C), "-", "")) & IIf(InStr("CFHLPZ45678,", C), ".", IIf(InStr("JQVXY01239.?", C), "-", "")) & IIf(InStr("56789.?", C), ".", IIf(InStr("01234,", C), "-", "")) & IIf(C = "?", ".", IIf(InStr(".,", C), "-", "")) & " ": Next
End Function
0
DJ.

C, 533 caractères

J'ai suivi les conseils de certains commentaires et suis passé à stdin. Tué environ 70 autres personnages à peu près.

#include <stdio.h>
#include <ctype.h>
char *u[36] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
main(){
char*v;int x;char o;
do{
o = toupper(getc(stdin));v=0;if(o>=65&&o<=90)v=u[o-'A'];if(o>=48&&o<=57)v=u[o-'0'+26];if(o==46)v=".-.-.-";if(o==44)v="--..--";if(o==63)v="..--..";if(o==32)v="/";if(v)printf("%s ", v);} while (o != EOF);
}
0
Will Bickford

C89 (388 caractères)

Ceci est incomplet car il ne gère pas encore les virgules, les arrêts complets et les requêtes.

#define P putchar
char q[10],Q,tree[]=
"EISH54V 3UF    2ARL   + WP  J 1TNDB6=X/ KC  Y  MGZ7 Q  O 8  90";s2;e(x){q[Q++]
=x;}p(){for(;Q--;putchar(q[Q]));Q=0;}T(int x,char*t,int s){s2=s/2;return s?*t-x
?t[s2]-x?T(x,++t+s2,--s/2)?e(45):T(x,t,--s/2)?e(46):0:e(45):e(46):0;}main(c){
while((c=getchar())>=0){c-=c<123&&c>96?32:0;if(c==10)P(10);if(c==32)P(47);else
T(c,tree,sizeof(tree)),p();P(' ');}}

Enveloppé pour la lisibilité. Seuls deux des sauts de ligne sont requis (un pour le #define, un après l'autre, qui pourrait être un espace). J'ai ajouté quelques caractères non standard mais je n'ai pas ajouté de caractères non 7 bits.

0
strager