Numéros de téléphone brouillés

19

Vous savez comment vous obtenez un message vocal et la connexion de la personne n'était pas excellente, et vous essayez de comprendre comment la rappeler, mais vous ne savez pas si c'était un "5" ou un "8". m'a dit?

Voilà ce défi.

La bonne nouvelle est que l'appelant a lu son numéro deux fois, mais qu'il est tronqué aux deux endroits.

Votre programme devrait recevoir des commentaires comme celui-ci:

5551231234 / 5551231234

Lorsque les dix premiers chiffres sont la première fois que le numéro de téléphone est dit dans la messagerie vocale et le deuxième ensemble est la deuxième fois qu'il est dit. Seulement ... ça ressemblera plus à ceci:

555?ABC1_36? / 55?522_1?234
  • Un chiffre suivi d'un point d'interrogation signifie que c'est la meilleure estimation pour ce chiffre (par exemple "5?" Signifie "probablement un 5, comparer avec répéter").
  • Un trait de soulignement indique un chiffre manquant connu, quelque chose de trop flou par statique pour être déchiffré du tout.
  • Les lettres ne sont que cela: des lettres. Traitez-les comme leurs chiffres respectifs
    • ABC -> 2, DEF -> 3, GHI -> 4, JKL -> 5, MNO -> 6, PQRS -> 7, TUV -> 8, WXYZ -> 9
    • Tous les exemples d'entrées utilisent des majuscules (vous pouvez omettre en toute sécurité un appel ToUpper ())
    • Si votre langue fonctionne mieux en minuscules, vous pouvez librement utiliser des minuscules pour l'entrée et omettre un appel ToLower (). Notez cela dans votre réponse.

Vous pouvez en outre assumer les appels de jugement suivants:

5? / _     -> 5  //5 is the best guess we have, use it
5? / 5?    -> 5  //uncertain, but matching
5? / 4?    -> ?  //conflict
 5 / 4     -> ?  //conflict
5? / 4     -> 4  //solid information overrides possible value
 5 / 4?    -> 5  //solid information overrides possible value
 _ / _     -> ?  //no information available

De plus, vous pouvez supposer que toutes les entrées contiendront des numéros de téléphone à dix chiffres, sans les points d'interrogation. Les entrées qui ne sont pas à dix chiffres (par exemple 1234567 / 1234567) peuvent être traitées comme insolubles (sortie falsey) ou renvoyer une erreur.

Contribution

Une ligne de caractères 0-9A-Z _?/, comme décrit ci-dessus.

Production

S'il peut être analysé en un seul numéro de téléphone à dix chiffres valide, entrez le numéro de téléphone. Sinon, affichez une forme quelconque d'indication d'erreur (par exemple -1, false ou une ligne vide).

Victoires les plus courtes, comme d'habitude.

Exemples d'entrées:

1234567890 / 1234567890
1234567890? / 1234567890
123456789_ / 1234567890
1234567890? / 123456789_
1234567890 / 1234567890?
1234567890 / 123456789_
123456789_ / 1234567890?
1234567890? / 1234567890?
1234567890? / 1234567891?
123456789_ / 123456789_
555CALLUS1 / 5552255871
404_12?6039 / 4041?1560_9
_GETREVENGE / 16?36?_2838_
1?691460_50 / 16_14609?50
61?08977211 / 612?897725?1
40?0INSTA__ / 8?00_NSTI?LL
3985_534?10 / 39?8?5053_10
7__7294?737 / 7797299?_37
28?897_384?1 / _8?89763861
271168090_ / 27116800?09
6802?148343 / 67?01148343
94_11628?2?6? / 9491162_47?
17?4285_689 / 1__26?52689
6_311?95_38 / 6731194?7?38
380?7DRAGON / 3807378?5?66
4?647_93236 / 5646?6?9__36
365?268898_ / 366267?7?984
GRATEDBATE / IRATEDBATE
5307_079?93 / ____8_____
535_3_0255 / 52?5_3_024?5
55_____088 / 54?2397207?7?
6_48398_95 / _946?398?6_5?
_0_312_3_1 / 81?53123?1?71
____1_____ / 64?255?508?61
8427820607 / 6?424?8?__6?07
50_3707__6 / 52?8375?74?56
615___8255 / 62?526?983?2?1?
__652618__ / 8365261__0
149___933_ / 1_9677?92?31
___7?281562 / 3438?28154?2
5?7?7?___8?3?7?4 / 57_855837_
605_272481 / 605427__81
86?569__731 / 88560?0?7721
1__91654?15 / 17?9?9165715
800NWABODE / 80069ABI?DE
8___9017_0 / 8_2494?12?9_
_024?5?91?470 / 304?17908?7_
42510704_2 / 4_51070492
9338737_89 / 93_873PLUS
327762_401 / 327_MASH01
33093_2058 / 3309_12058
4061_33578 / 40619_3578
559_383197 / 559938_197
94_9746084 / 9459746_84
1_37655238 / 163POLKA_T
_672FRIZZY / 767237499_
8_76318872 / TIP63188_2
51_8404321 / 5178404_21
358_030314 / 358603_314
2597_85802 / 25979_5802
77141_1408 / 7714_91408
330858_457 / 330_586457
4686079_39 / 46_6079239
86457508_6 / 8_45750826
523226626_ / _23BANNANA
_ISSY_ISSY / 44__9548?79?
6?00B_YJILT / 800289KILL?
2?52803___0 / 1526?0390?61?
FI?ND___T?HE / EAS?T?EREGGS?
0_231?95_38 / 0723194?7?38
0?647_39236 / 0646?6?3__36
025?267798_ / 06?6265?9?984
0061_33578 / _0619_3578

J'ai seulement assuré que tous les cas de bord possibles sont couverts (les 11 premières entrées), mais à part cela, c'est à peu près aléatoire.

Mise à jour

Quatre entrées en bas ajoutées avec des zéros de tête (à la suggestion de Jonathan Allan).

Sortie correcte pour les entrées d'échantillon:

https://pastebin.com/gbCnRdLV

Basé sur la sortie de l'entrée de Jonathan Allan (la sortie formatée était idéale).

Draco18s
la source
Devons-nous prendre les entrées comme une seule chaîne, séparées par " / ", ou pouvons-nous simplement les prendre comme deux entrées standard?
L3viathan
@ L3viathan J'avais initialement conçu l'idée comme devant prendre une seule chaîne.
Draco18s
7
@ Draco18s single string n'apporte rien au défi
fəˈnɛtɪk
1
@ fəˈnɛtɪk Personne n'a rien dit dans le bac à sable, mais je n'ai rien contre l' utilisation de paires d'entrée. C'était juste la façon dont je l'avais conçu à l'origine.
Draco18s
1
Qui laisse un message vocal en utilisant des lettres pour son numéro de téléphone?!
Jonathan Allan

Réponses:

3

Gelée , 84 octets

+4 octets - Je pense que cela devrait probablement se comporter de la même manière dans tous les cas, j'ai donc reconverti les entiers de recherche du clavier en caractères numériques en utilisant +49Ọ.

”?e‘ḣ@µ”_eḤ‘ẋ@
;Ṃµ68DṬ+3RØAṁẇ@€FT+49Ọȯµ€Fṡ2i”?Ḃ$ÐḟÇ€
ḟ⁶ṣ”/Ç€ZLÐṂ€Q€LỊ$ÐfF€Ḣ€ḟ”_µL⁼⁵ȧ

Une fonction qui prend la chaîne au format spécifié et renvoie le numéro de téléphone sous forme de liste de caractères ou zéro si non valide. En tant que programme, cela est imprimé comme s'il s'agissait d'une chaîne.

La façon dont cela fonctionne, ils pourraient répéter le nombre de fois
(par exemple "123456789_ / 123456789_ / 1234567890")
... ou même le dire une seule fois, et la logique définie s'appliquera.

Essayez-le en ligne! ou consultez tous les exemples d'entrées .

Comment?

”?e‘ḣ@µ”_eḤ‘ẋ@ - Link 1, helper to vary the length of a 2-slice: list s
”?             - literal '?'
  e            - exists in s                   (1 or 0)
   ‘           - increment                     (2 or 1)
    ḣ@         - head with reversed @rguments  (s or s[:1] - removes 2nd value if not '?')
      µ        - monadic chain separation, call that t
       ”_      - literal '_'
         e     - exists in t                   (1 or 0)
          Ḥ    - double                        (2 or 0)
           ‘   - increment                     (3 or 1)
            ẋ@ - repeat t that many times      (t*3 or t - [`_`]->['_','_','_'])

;Ṃµ68DṬ+3RØAṁẇ@€FT+49Ọȯµ€Fṡ2i”?Ḃ$ÐḟÇ€ - Link 2, reformat a phone number: char list of [0-9][A-Z], p
;                                     - concatenate p with
 Ṃ                                    - minimum of p - (?<_<0<1<...<9<A<...<Z - never "?" however, since it only follows a digit.)
                                      -   - this is simply to make a 2-slice with the last character on the left, as used at the very end of this link.
  µ                                   - monadic chain separation call that q
                       µ€             - monadic chain separation, for €ach v in q do:
   68                                 -   literal 68
     D                                -   cast to a decimal list -  [6,8]
      Ṭ                               -   untruth                -  [0,0,0,0,0,1,0,1]
       +3                             -   add 3                  -  [3,3,3,3,3,4,3,4]
         R                            -   range                  -  [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3,4],[1,2,3],[1,2,34]]
          ØA                          -   uppercase alphabet     -  ABCDEFGHIJKLMNOPQRSTUVWXYZ
            ṁ                         -   mould like the range ^ -  [ABC,DEF,GHI,JKL,MNO,PQRS,TUV,WXYZ]
             ẇ@€                      -   sublist v exists in that? for €ach, with reversed @rguments
                F                     -   flatten        (e.g. 'E' -> [0,1,0,0,0,0,0,0]; '4' -> [0,0,0,0,0,0,0,0]
                 T                    -   truthy indexes (e.g. 'E' -> [2]; '4' -> [])
                  +49                 - add 49
                     Ọ                - cast to character
                      ȯ               -   or             (e.g. 'E' -> [3]; '4' -> '4')
                         F           - flatten
                          ṡ2          - all slices of length 2
                                 Ðḟ   - filter discard if:
                                $     -   last two links as a monad:
                            i         -     first index of
                             ”?       -     literal '?'   (first index returns 0 if none exists)
                               Ḃ      -   mod 2 (so this filter discards pairs starting with '?')
                                   Ç€ - call the last link (1) as a monad for €ach slice

ḟ⁶ṣ”/Ç€ZLÐṂ€Q€LỊ$ÐfF€Ḣ€ḟ”_µL⁼⁵ȧ - Main link: string (or char list) s
ḟ                               - filter discard any:
 ⁶                              - literal ' '
  ṣ                             - split on:
   ”/                           - literal '/'
     Ç€                         - call the last link (2) as a monad for €ach
       Z                        - transpose
         ÐṂ€                    - filter, for €ach, keep items with minimal:
        L                       -   length
            Q€                  - de-duplicate €ach
                 Ðf             - filter keep items with:
                $               - last two links as a monad:
              L                 -   length
               Ị                -   insignificant? (=1 effectively here)
                   F€           - flatten €ach
                     Ḣ€         - head €ach
                       ḟ        - filter discard any of:
                        ”_      -   literal '_'
                          µ     - monadic chain separation, call that r
                           L    - length(r)
                             ⁵  - literal 10
                            ⁼   - equal?
                              ȧ - and r (0 if r did not result in a 10-digit list, else r)
Jonathan Allan
la source
Il semble qu'il puisse y avoir une erreur, 55_____088 / 54?2397207?7?devrait se résoudre à 5523972088: tous les chiffres manquants sont présents et les chiffres incertains à droite sont disponibles à gauche. Tous les cas simplistes fonctionnent cependant.
Draco18s
Ah, j'ai supprimé ce que je pensais être un filtre redondant, ce n'était pas le cas. Correction ...
Jonathan Allan
J'y étais avant - et ce n'était pas du golf! ;)
Draco18s
Ooof qui m'a pris un certain temps (j'ai trouvé un bogue différent pendant que je le testais), l'a ramené au même nombre d'octets que d'ajouter simplement le filtre lors de la correction de cela, alors (ouf).
Jonathan Allan
@ Draco18s - tout vous semble bien? Il peut être utile de fournir la sortie attendue pour les cas de test dans la question, ou peut-être simplement de séparer les cas non valides.
Jonathan Allan
7

Python 2 , 314 307 274 octets

lambda s:g(*''.join(q<n<"["and`(int(n,36)-4-(n>"R")-(n>"Y"))//3`or n for n in s).split(" / "))
def g(a,b,s=str.startswith):
 if b:c,d,e,f=a[0],a[1:],b[0],b[1:];b=(c==e and[c,q][c=="_"]or"_"in c+e and min(c,e)or[q,c,e][s(f,q)-s(d,q)])+g(d[s(d,q):],f[s(f,q):])
 return b
q="?"

Essayez-le en ligne!

ovs
la source
5

Python 3, 549 530 509 453 449 410 406 394 393 391 octets

Je suis sûr que cela peut être amélioré, mais c'est un début:

def f(e,z,q="?",u=str.isnumeric):
 if e+z in(e,z):return""
 o,O,t,T,*x=e[0],e[1:2],z[0],z[1:2],e[1:],z[1:]
 if"?"in o+t:return f([e,x[0]][o==q],z)
 if u(o):
  if u(t):return t+f(*x)if O==q!=T else o+f(*x)if o==t or T==q!=O else 1
  return o+f(*x)
 if u(t):return t+f(*x)
def g(s):
 for a,b in zip(map(chr,range(65,91)),"2223334445556667777888999"):s=s.replace(a,b)
 return f(*s.split(" / "))

J'utilise str.translatepour les lettres et une fonction wrapper gpour faire les entrées dans le format dans lequel je les veux. La fonction réelle fest récursive et échouera pour les entrées ambiguës. Cependant, j'ai encore beaucoup de répétitions, donc je suis sûr qu'il y a beaucoup de place pour l'amélioration.

Améliorations:

  • économisé 19 octets en combinant les conditions
  • enregistré 21 octets avec ternaires
  • économisé 56 octets en utilisant une compréhension de dictionnaire au lieu du dictionnaire manuel, grâce à @TuukkaX
  • économisé 4 octets en passant à la méthode suggérée par @ovs, avec l'amélioration de @ TuukkaX
  • enregistré 38 octets avec des améliorations de @ovs (et le dernier espace blanc amovible supprimé)
  • enregistré 4 octets en plaçant la définition str.isnumericdans un argument de mot clé
  • enregistré 12 octets avec des opérateurs de comparaison combinés (par exemple T==q!=O)
  • 1 octet enregistré en tournant not(e or z)dans e+z in(e,z).
  • enregistré 2 octets en enregistrant les fichiers fréquemment utilisés (E,Z)
L3viathan
la source
Cela contient une compréhension du dictionnaire qui ne contient pas les valeurs par défaut de la ligne supérieure. Je déteste les séquences de 3, mais celles-ci pourraient être remplacées par des mathématiques.
Yytsi
@ovs Nice. L'alphabet peut être changé en map(chr,range(65,91))cependant.
Yytsi
2
RE: En faisant un wiki communautaire pour renoncer à la réputation, le consensus serait non , acceptez simplement l'aide aimable et créditez-la comme vous.
Jonathan Allan
1
Je jure que chaque fois que je reviens ici, cette réponse devient plus courte: D
Draco18s
3

JavaScript (ES6), 180 190 188 octets

Modifier: +10 +9 octets pour se conformer à la règle de sortie falsifiée


Prend les deux chaînes d'entrée dans la syntaxe de curry (a)(b). Renvoie soit falseune chaîne représentant le numéro de téléphone supposé.

a=>b=>!(s=(F=a=>a.match(/(.\??)|_/g).map(([x,y])=>(x<=9?++x:parseInt(x,36)*.32-(x>'Y'))|(x!='_'&!y)*16))(a).map((x,i)=>(x=(d=x^(y=F(b)[i]),x>y)?x:y)&&(d&16|!(d%x))?--x&15:a).join``)[10]&&s

Comment ça fonctionne

Étape # 1 - Analyser les chaînes d'entrée

Nous définissons d'abord la F()fonction qui traduit une chaîne en un tableau d'entiers en appliquant les règles suivantes:

  • le trait de soulignement est converti en 0
  • un chiffre N ou une lettre équivalente est converti en (N + 1) OU 16 (par exemple "2" → 19, "R" → 24)
  • un chiffre N ou une lettre équivalente suivie d'un point d'interrogation est convertie en N + 1 (par exemple "2?" → 3, "R?" → 8)

Ce qui peut être interprété dans l'autre sens comme suit:

  • 0 inconnu
  • [ 1 .. 10 ]peu fiable
  • [ 17 .. 26 ]fiable

Nous appliquons F()à la fois aet b. Cela nous donne une paire d'entiers (x, y) pour chaque chiffre du numéro de téléphone, correspondant aux deux interprétations possibles.

Étape # 2 - Deviner les chiffres

Pour chaque paire (x, y) , nous calculons:

  • d = x XOR y
  • x = MAX (x, y) → les valeurs fiables sont toujours préférées aux valeurs non fiables

Si x == 0 , cela signifie que les deux entrées sont des caractères de soulignement. Donc, le chiffre est inconnu dans ce cas.

Si x! = 0 , nous pouvons déduire le chiffre en toute sécurité si l'une des conditions suivantes est remplie:

condition       | interpretation
----------------+------------------------------------------------------
(d AND 16) != 0 | one input is unreliable and the other one is reliable
d == 0          | both inputs are identical
d == x          | one input is an underscore

Les deux dernières conditions peuvent être fusionnées avec !(d % x). D'où la formule finale:

x && (d & 16 || !(d % x))

Si vrai, nous convertissons x en chiffre deviné en calculant (x - 1) ET 15 .

Cas de test

(Seuls les 50 premiers parce que l'extrait de console ne peut pas prendre en charge plus d'historique de sortie.)

Arnauld
la source
1234567890? / 1234567890?devrait se résoudre à 1234567890. À l'heure actuelle, votre code sort, 123456789?ce qui est encore moins informatif que l'entrée. Assume: 5? / 5? -> 5 //uncertain, but matching
Draco18s
@ Draco18s Contrairement à ce que j'ai déclaré, j'ai inclus 51 cas de test. Le premier a donc été abandonné et tout a été décalé d'une ligne. (Maintenant corrigé. Désolé à ce sujet.)
Arnauld
Aaah. Néanmoins, il devrait produire une sorte de valeur de falsey ou d'erreur pour ces cas de test. Mais sinon, ça a l'air bien.
Draco18s
2

Perl 5 , 211 octets

... sans retrait et \ n nouvelles lignes

@i=map{y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/22233344455566677778889999/;$_}split' / ',shift;
print map{
  $_=join'',map{s,(\d\??|_),,;$1}@i;
  /((\d)\??\2\??|(\d)\??_|_(\d)\??|(\d)\d\?|\d\?(\d))$/;$2//$3//$4//$5//$6//'?'
}1..10

Essayez-le en ligne!

Kjetil S.
la source
On dirait qu'il revient "du mieux qu'il peut" ( 83652618?0) plutôt qu'une sorte de valeur de falsey ou d'erreur.
Draco18s
C'est ce que le puzzle voulait si je ne me trompe pas. Regardez les affaires sous le titre "Vous pouvez en outre assumer les appels de jugement suivants". Ou pas?
Kjetil S.
Désolé, je n'ai jamais reçu de notification de votre réponse (pas de mention). La section que j'avais faite pour les appels de jugement utilise un? pour indiquer qu'il n'y a aucun moyen de résoudre les informations manquantes, qui devraient ensuite passer à la section Sortie:...Otherwise output some form of error indication (e.g. -1, false, or an empty line).
Draco18s
2

Rétine, 150 140 136 octets

Enregistré quelques octets grâce à Kritixi Lithos

T`?L`#22233344455566677778889
./.

(?<=(\d)(\w#?){9}).#|.#(?=(\w#?){9}(\d)(?!#))
$1$4
#

_(?=.{9}(.))|(?<=(.).{9})_
$1$2
^(\d*)\1$|.*
$1

Essayez-le en ligne!

Explication:

La première ligne transforme tout ? dans l'entrée en# et toutes les lettres en leurs équivalents numériques. Nous supprimons ensuite les espaces et /de l'entrée. Les deux lignes suivantes prennent en charge les cas de «supposition contre certitude» (par exemple, 5? \ 4seraient remplacés par 4 \ 4). Après avoir supprimé tous les #s, les lignes 8 et 9 traitent des cas «nombre vs _» ( _ \ 3devient 3 \ 3). Ensuite, si les deux moitiés de la chaîne correspondent, nous conservons les 10 premiers chiffres. Sinon, le numéro de téléphone n'est pas valide, nous supprimons tout.

Solution alternative de 160 octets qui fonctionne pour les numéros de téléphone de longueur arbitraire (et de taille égale): TIO

accro aux mathématiques
la source
Vous pouvez changer la (/|_)pour [/_]sauver 1 octet. Je pense aussi que vous pouvez utiliser ;au lieu dex sorte que[^x] peut devenir\w
Kritixi Lithos
1

PHP, 251 236 octets

for(;a&$c=preg_replace(["#[^_?](?!\?)#","#_#"],["$0k","?<"],join("-",$argv))[++$i];)${$k+="-"==$c}.=$c<_&$c>=A?0|(ord($c)-($c>W)-($c>P)-59)/3:$c;for(;$c=${1}[$k+1];)echo($n=${1}[$k])==($m=${2}[$k++])|($b=${2}[$k++])!=$c?$c>$b?$n:$m:"?";

prend l'entrée de la ligne de commande; courir avec-nr ou essayer en ligne .

panne

# A: transform input
                                    # 2. replace single chars with two-character chunk and make sortable:
                                    #   replace "_" with "?<", append "k" to everything else not followed by "?"
for(;a&$c=preg_replace(["#[^_?](?!\?)#","#_#"],["$0k","?<"],join("-",$argv))[++$i];)    # (unknown "<" < unsure "?" < certain "k")
${$k+="-"==$c}.=                # if "-", next argument
        $c<_&$c>=A              # if letter
            ?0|(ord($c)-($c>W)-($c>P)-59)/3 # then translate to digit
            :$c                             # else don´t
    ;
# B: evaluate
for(;$c=${1}[$k+1];)            # loop through arguments: $c=command 2
    echo
        ($n=${1}[$k])                   # $n=digit 2
        ==                          # if digits are equal
        ($m=${2}[$k++])                 # $m=digit 3
        |
        ($b=${2}[$k++])             # $b=command 3
        !=$c                        # or "commands" are not
            ?$c>$b?$n:$m            # then get the one with the more definitive "command"
            :"?"                    # else conflict/unknown
    ;

golf

  • preg_replace premier: -8 octets
  • join: -2
  • $$k au lieu de $t[$k] : -5
Titus
la source
1

PHP, 200 + 8 octets

inspiré par la solution Arnaulds .

for($s=join($argv);$c=ord($s[$i++]);$i+=$x)$t[]=$c>90?63:15&($c<65?$c:($c-($c>80)-($c>87)-59)/3)|16*$x="?"==$s[$i];for(;$p++<10;)echo chr(($e=$t[$p]^$d=$t[$p+10])&48|!(15&$e)?min($t[$p],$d)&15|48:63);

prend l'entrée des arguments de ligne de commande; courir avec -nrou essayer en ligne .

modifications pour se conformer à la restriction de sortie d'erreur: (imprimerX pour un numéro incomplet):

  • retirer |48 (-3 octets)
  • remplacer echo chr(...);par $r.=...;echo$r>1e10?X:$r;(+11 octets)

panne

for($s=join($argv);$c=ord($s[$i++]);    # loop through characters of arguments
    $i+=$x)                             # skip "?"
$t[]=
    $c>90                               # if "_"
        ?63                             # then 32+16+15
        :                               # else
            15&(                            # lower 4 bits of
            $c<65                               # if digit
            ?$c                                 # then digit
            :($c-($c>80)-($c>87)-59)/3          # else letter mapped to digit
        )
        |16*$x="?"==$s[$i]                  # if next char is "?", add 16
;
for(;$p++<10;)echo chr( # loop through translated arguments
    (
        $e=$t[$p]^      # 2. $e=difference
        $d=$t[$p+10]    # 1. $d=char from 2nd argument
    )&48                # if certainties differ
    |!(15&$e)           #    or digits do not
    ?min($t[$p],$d)&15|48   # then pick the more definite digit (15|48 -> "?")
    :63             # else "?"
);

golf

  • solution de contournement preg_replace_callback (-10 octets)
  • compter sur une entrée à 10 chiffres (-9)
  • et golf supplémentaire (-8)
  • supprimé joindélimiteur (-7)
  • $xaffectation déplacée à la fin (-2)
Titus
la source
1

Perl 5 -pl , 173 octets

sub t{$_=pop;y/A-Z/22233344455566677778889999/;/_|\d\??/g}@e=m|\S+|g;@a=t$e[0];$_=join"",map{$_.=shift@a;s/^(.+)\1$/$1/||s/_//||s/..../_/||s/.\?//;$_}t$e[2];s/\?//;$_ x=!/_/

Essayez-le en ligne!

Xcali
la source