Nomor Telepon yang kacau

19

Anda tahu bagaimana Anda mendapatkan pesan suara dan koneksi orang itu tidak bagus, dan Anda mencoba mencari cara untuk memanggil mereka kembali, tetapi Anda tidak yakin apakah itu "5" atau "8" yang mereka kata?

Itulah tantangan ini.

Berita baiknya adalah bahwa penelepon membacakan nomor mereka dua kali, tetapi rusak di kedua tempat.

Program Anda harus mengambil input seperti ini:

5551231234 / 5551231234

Di mana sepuluh digit pertama adalah pertama kalinya nomor telepon dikatakan dalam pesan suara dan set kedua adalah yang kedua kali dikatakan. Hanya ... itu akan terlihat lebih seperti ini:

555?ABC1_36? / 55?522_1?234
  • Angka yang diikuti oleh tanda tanya berarti bahwa itu adalah tebakan terbaik untuk digit itu (mis. "5?" Berarti "mungkin angka 5, bandingkan dengan yang diulang").
  • Garis bawah menunjukkan angka yang hilang yang diketahui, sesuatu yang terlalu kabur oleh statis untuk diuraikan sama sekali.
  • Surat hanya itu: surat. Perlakukan mereka sebagai digit masing-masing
    • ABC -> 2, DEF -> 3, GHI -> 4, JKL -> 5, MNO -> 6, PQRS -> 7, TUV -> 8, WXYZ -> 9
    • Semua input sampel menggunakan huruf besar (Anda dapat dengan aman menghilangkan panggilan ToUpper ())
    • Jika bahasa Anda berfungsi lebih baik dalam huruf kecil, Anda dapat dengan bebas menggunakan huruf kecil untuk input dan menghilangkan panggilan ToLower (). Catat itu dalam jawaban Anda.

Anda juga dapat menerima panggilan penilaian berikut:

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

Selain itu Anda dapat mengasumsikan bahwa semua input akan berisi nomor telepon sepuluh digit, tidak termasuk tanda tanya. Input yang bukan sepuluh digit (mis. 1234567 / 1234567) Dapat diperlakukan sebagai tidak dapat diselesaikan (output falsey) atau menimbulkan kesalahan.

Memasukkan

Satu baris karakter 0-9A-Z _?/, seperti dijelaskan di atas.

Keluaran

Jika dapat diuraikan menjadi satu nomor telepon sepuluh digit yang valid, keluarkan nomor telepon itu. Kalau tidak, output beberapa bentuk indikasi kesalahan (misalnya -1, false, atau baris kosong).

Kemenangan terpendek, seperti biasa.

Input sampel:

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

Saya hanya mengasuransikan bahwa setiap kemungkinan edge-case tertutup (11 entri pertama), tetapi selain itu, ini cukup acak.

Memperbarui

Empat entri di bagian bawah ditambahkan dengan angka nol di depan (atas saran Jonathan Allan).

Output yang benar untuk input sampel:

https://pastebin.com/gbCnRdLV

Berdasarkan output dari entri Jonathan Allan (output yang diformat adalah ideal).

Draco18s
sumber
Apakah kita harus mengambil input sebagai string tunggal, dipisahkan oleh " / ", atau dapatkah kita menganggapnya sebagai dua input standar?
L3viathan
@ L3viathan Saya awalnya mengira ide harus mengambil satu string.
Draco18s
7
@Straco18s string tunggal tidak membawa apa pun untuk tantangan
fəˈnɛtɪk
1
@ fəˈnɛtɪk Tidak ada yang mengatakan apa pun di kotak pasir, tapi saya tidak keberatan menggunakan pasangan input. Itu hanya cara saya awalnya menyusunnya.
Draco18s
1
Siapa yang meninggalkan voicemail menggunakan surat untuk nomor telepon mereka ?!
Jonathan Allan

Jawaban:

3

Jelly , 84 byte

+4 byte - Saya pikir ini mungkin harus berperilaku sama dalam semua kasus, jadi saya telah mengubah bilangan bulat pencarian keypad kembali ke digit-karakter menggunakan +49Ọ.

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

Fungsi yang mengambil string dalam format yang ditentukan dan mengembalikan nomor telepon sebagai daftar karakter atau nol jika tidak valid. Sebagai sebuah program, ini dicetak seolah-olah itu sebuah string.

Cara kerjanya, mereka dapat mengulangi angka lebih banyak kali
(misalnya "123456789_ / 123456789_ / 1234567890")
... atau bahkan hanya mengatakannya sekali, dan logika yang didefinisikan akan berlaku.

Cobalah online! , atau lihat semua input sampel .

Bagaimana?

”?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
sumber
Sepertinya mungkin ada kesalahan, 55_____088 / 54?2397207?7?harus diselesaikan 5523972088: semua digit yang hilang ada dan angka yang tidak pasti di sebelah kanan tersedia di sebelah kiri. Semua kasus sederhana berjalan.
Draco18s
Ah, saya menghapus apa yang saya pikir adalah filter yang berlebihan, bukan itu. Memperbaiki ...
Jonathan Allan
Pernah ke sana sebelumnya - dan itu bukan golf! ;)
Draco18s
Ooof yang memakan waktu beberapa saat (saya menemukan bug yang berbeda saat saya mengujinya), mengembalikannya ke jumlah byte yang sama dengan hanya menambahkan kembali filter ketika memperbaiki itu jadi (wah).
Jonathan Allan
@ Draco18s - apakah semuanya terlihat baik bagi Anda? Mungkin bagus untuk memberikan hasil yang diharapkan untuk kasus uji dalam pertanyaan, atau mungkin hanya memisahkan yang tidak valid.
Jonathan Allan
7

Python 2 , 314 307 274 byte

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="?"

Cobalah online!

ovs
sumber
5

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

Saya yakin ini bisa diperbaiki, tapi ini awal:

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(" / "))

Saya menggunakan str.translateuntuk surat-surat, dan fungsi pembungkus guntuk membuat input dalam format yang saya inginkan. Fungsi sebenarnyaf adalah rekursif, dan akan gagal untuk input yang ambigu. Saya masih memiliki banyak repitisi di sana, jadi saya yakin ada banyak ruang untuk perbaikan.

Perbaikan:

  • disimpan 19 byte dengan menggabungkan kondisi
  • menyimpan 21 byte dengan terner
  • menyimpan 56 byte menggunakan pemahaman kamus alih-alih kamus manual, terima kasih kepada @TuukkaX
  • disimpan 4 byte dengan beralih ke metode yang disarankan oleh @ovs, dengan peningkatan @ TuukkaX
  • menyimpan 38 byte dengan peningkatan dari @ovs (dan ruang kosong yang bisa dilepas terakhir dihapus)
  • menyimpan 4 byte dengan menempatkan definisi str.isnumericdalam argumen kata kunci
  • menyimpan 12 byte dengan operator perbandingan gabungan (mis. T==q!=O)
  • disimpan 1 byte dengan mengubahnya not(e or z)menjadi e+z in(e,z).
  • menyimpan 2 byte dengan menyimpan yang sering digunakan (E,Z)
L3viathan
sumber
Ini mengandung pemahaman kamus yang tidak mengandung default baris atas. Saya benci urutan 3, tetapi itu mungkin diganti dengan matematika.
Yytsi
@ovs Bagus. Alfabet dapat diubah menjadi map(chr,range(65,91))sekalipun.
Yytsi
2
RE: Menjadikan ini wiki komunitas untuk mengesampingkan reputasi, konsensusnya adalah tidak , hanya menerima bantuan yang baik, dan menghargai itu seperti yang Anda miliki.
Jonathan Allan
1
Saya bersumpah setiap kali saya kembali ke sini, jawaban ini semakin pendek: D
Draco18s
3

JavaScript (ES6), 180 190 188 byte

Edit: +10 +9 byte untuk mematuhi aturan output falsy


Mengambil dua string input dalam sintaks currying (a)(b). Mengembalikan salah satu falseatau string yang mewakili nomor telepon yang ditebak.

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

Bagaimana itu bekerja

Langkah # 1 - Mengurai string input

Kami pertama-tama mendefinisikan F()fungsi yang menerjemahkan string ke dalam array bilangan bulat dengan menerapkan aturan berikut:

  • garis bawah diubah menjadi 0
  • digit N atau huruf setara dikonversi ke (N + 1) ATAU 16 (mis. "2" → 19, "R" → 24)
  • digit N atau huruf setara diikuti dengan tanda interogasi dikonversi ke N + 1 (mis. "2?" → 3, "R?" → 8)

Yang bisa diartikan sebaliknya sebagai berikut:

  • 0 tidak diketahui
  • [ 1 .. 10 ] tidak dapat diandalkan
  • [ 17 .. 26 ] dapat diandalkan

Kami berlaku F()untuk keduanya adan b. Ini memberi kita sepasang bilangan bulat (x, y) untuk setiap digit dalam nomor telepon, sesuai dengan dua interpretasi yang mungkin.

Langkah # 2 - Menebak angka

Untuk setiap pasangan (x, y) , kami menghitung:

  • d = x XOR y
  • x = MAX (x, y) nilai yang dapat diandalkan selalu lebih disukai daripada yang tidak dapat diandalkan

Jika x == 0 , itu berarti bahwa kedua input adalah karakter garis bawah. Jadi, digitnya tidak diketahui dalam hal ini.

Jika x! = 0 , kami dapat menyimpulkan digit dengan aman jika salah satu dari kondisi berikut ini benar:

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

Dua kondisi terakhir dapat digabungkan !(d % x). Maka rumus terakhir:

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

Jika benar, kami mengonversi x kembali ke angka tebakan dengan menghitung (x - 1) DAN 15 .

Uji kasus

(Hanya 50 yang pertama karena cuplikan konsol tidak dapat mendukung lebih banyak riwayat keluaran.)

Arnauld
sumber
1234567890? / 1234567890?harus memutuskan untuk 1234567890. Saat ini output kode Anda 123456789?yang bahkan kurang informatif daripada input. Assume: 5? / 5? -> 5 //uncertain, but matching
Draco18s
@ Draco18s Berlawanan dengan apa yang saya nyatakan, saya memasukkan 51 kasus uji. Jadi yang pertama dijatuhkan dan semuanya bergeser satu baris. (Sekarang sudah diperbaiki. Maaf soal itu.)
Arnauld
Aaah. Namun, itu harus menampilkan semacam nilai kesalahan atau kesalahan untuk kasus-kasus uji. Tetapi sebaliknya terlihat bagus.
Draco18s
2

Perl 5 , 211 byte

... tanpa lekukan dan \ n baris baru

@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

Cobalah online!

Kjetil S.
sumber
Sepertinya mengembalikan "yang terbaik yang bisa" ( 83652618?0) daripada semacam nilai kesalahan atau kesalahan.
Draco18s
Itulah yang diinginkan puzzle jika saya tidak salah. Lihatlah kasus-kasus di bawah judul "Anda juga dapat menerima panggilan penilaian berikut". Atau tidak?
Kjetil S.
Maaf, tidak pernah mendapat notifikasi balasan Anda (tidak disebutkan). Bagian yang saya lakukan untuk panggilan penilaian menggunakan a ?untuk menunjukkan bahwa tidak ada cara untuk menyelesaikan informasi yang hilang, yang kemudian akan jatuh ke bagian Keluaran:...Otherwise output some form of error indication (e.g. -1, false, or an empty line).
Draco18s
2

Retina, 150 140 136 byte

Disimpan beberapa byte berkat Kritixi Lithos

T`?L`#22233344455566677778889
./.

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

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

Cobalah secara Online!

Penjelasan:

Baris pertama mengubah semua ?input menjadi #dan semua huruf menjadi setara numerik mereka. Kami kemudian menghapus spasi dan /dari input. Dua baris berikutnya menangani kasus "tebak vs. kepastian" (mis. 5? \ 4Akan diganti oleh 4 \ 4). Setelah menghapus semua #s, baris 8 dan 9 berurusan dengan _case "number vs. " ( _ \ 3menjadi3 \ 3 ). Kemudian, jika kedua bagian dari senar cocok, kami menyimpan 10 digit pertama. Jika tidak, nomor telepon tidak valid sehingga kami menghapus semuanya.

Solusi 160 byte alternatif yang berfungsi untuk nomor telepon yang panjangnya sewenang-wenang (dan ukurannya sama): TIO

pecandu matematika
sumber
Anda dapat mengubah (/|_)to [/_]untuk menghemat 1 byte. Juga saya pikir Anda bisa menggunakan ;bukan xsehingga [^x]bisa menjadi\w
Kritixi Lithos
1

PHP, 251 236 byte

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:"?";

mengambil input dari baris perintah; jalankan dengan -nratau coba online .

kerusakan

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

bermain golf

  • preg_replace pertama: -8 byte
  • join: -2
  • $$kbukannya $t[$k]: -5
Titus
sumber
1

PHP, 200 + 8 byte

terinspirasi oleh solusi 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);

mengambil input dari argumen baris perintah; jalankan dengan -nratau coba online .

modifikasi untuk memenuhi batasan keluaran kesalahan: (cetak Xuntuk nomor yang tidak lengkap):

  • hapus |48(-3 byte)
  • ganti echo chr(...);dengan $r.=...;echo$r>1e10?X:$r;(+11 bytes)

kerusakan

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

bermain golf

  • bekerja di sekitar preg_replace_callback(-10 byte)
  • mengandalkan input 10 digit (-9)
  • dan golf tambahan (-8)
  • joinpembatas yang dihapus (-7)
  • pindah $xtugas sampai akhir (-2)
Titus
sumber
1

Perl 5 -pl , 173 byte

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=!/_/

Cobalah online!

Xcali
sumber