Nomor aslinya

36

Pedoman

Skenario

John memiliki nomor penting, dan dia tidak ingin orang lain melihatnya.

Dia memutuskan untuk mengenkripsi nomor tersebut, menggunakan langkah-langkah berikut:

Nomornya selalu merupakan urutan yang tidak menurun (mis. "1123")

Dia mengubah setiap digit menjadi kata-kata bahasa Inggris. (mis. "123" -> "ONETWOTHREE")

Dan kemudian, atur ulang surat secara acak. (mis. "ONETWOTHREE" -> "ENOWTOHEETR")

John merasa bahwa nomornya aman untuk melakukannya. Bahkan, enkripsi seperti itu dapat dengan mudah didekripsi :(


Tugas

Dengan diberikan string terenkripsi, tugas Anda adalah mendekripsi dan mengembalikan nomor aslinya.


Aturan

  • Ini adalah kode golf, jadi jawaban tersingkat dalam byte menang
  • Anda dapat mengasumsikan bahwa string input selalu valid
  • String input hanya berisi huruf besar
  • Nomor aslinya selalu diatur dalam urutan menaik
  • Anda dapat mengembalikan nomor dalam format string atau integer
  • Huruf-huruf hanya akan dikocok antara satu kata, bukan antara seluruh string.
  • Jumlahnya hanya dari 1 hingga 9 inklusif ( ONEhingga NINE)

Kemungkinan String yang Tidak Diuraikan

Berikut adalah daftar string tepat setelah mereka dikonversi ke string dari angka-angka:

 1 -> ONE 
 2 -> TWO
 3 -> THREE
 4 -> FOUR
 5 -> FIVE
 6 -> SIX
 7 -> SEVEN
 8 -> EIGHT
 9 -> NINE

Contohnya

"NEO" -> 1

"ENOWOT" -> 12

"EONOTWHTERE" -> 123

"SNVEEGHEITNEIN" -> 789

"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789

"NOEWOTTOWHEERT" -> 1223

Amorris
sumber
5
Dalam semua kasus uji, hanya huruf dalam kata yang diacak, bukan huruf di antara kata. Akankah itu selalu terjadi?
xnor
1
@ xnor Itu akan selalu terjadi. Saya telah mengedit pertanyaan.
Amorris
1
maka Anda perlu mengubah ini ".... (mis." ONETWOTHREE "->" TTONWOHREEE ")"
J42161217
2
@ TessellatingHeckler: Urutan non-ketat meningkat adalah ketika nomor berikutnya bisa sama dengan mantan sebelumnya. 1-1-1-2-2-3 (tidak meningkatkan secara ketat) dibandingkan dengan 1-2-3-4-5 (meningkat secara ketat)
koita_pisw_sou
1
Secara teknis, ini adalah penyandian, bukan enkripsi, karena tidak ada kunci.
Patrick Roberts

Jawaban:

5

Jelly ,  38  37 byte

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ

Tautan monadik yang mengambil daftar karakter (string) dan mengembalikan integer.

Cobalah online!

Penggunaan sebuah sangat berbeda metode untuk Pietu1998 Jelly jawaban , namun memiliki jumlah byte yang sama ( saya benar-benar berpikir itu mungkin itu berakhir kurang)!

Tidak mengandalkan monotonitas dari nomor asli (jadi input HTREEWTONOEakan berfungsi misalnya).

Bagaimana?

Pertama-tama perhatikan bahwa kata-kata itu sendiri (dan oleh karena itu setiap anagram daripadanya) semuanya dapat diubah menjadi yang panjang 4 dengan menghapus Rs, Gs dan Ss dan mengganti setiap Os dengan dua karakter (katakan "12") dan setiap Xs dengan tiga karakter ( katakan "345").

letters  -> -RGS  -> O:12, X:345
ONE         ONE      12NE
TWO         TWO      TW12
THREE       THEE     THEE
FOUR        FOU      F12U
FIVE        FIVE     FIVE
SIX         IX       I345
SEVEN       EVEN     EVEN
EIGHT       EIHT     EIHT
NINE        NINE     NINE

Kami kemudian dapat memetakan produk dari ordinals karakter-karakter tersebut ke angka 1 hingga 9 menggunakan modulo aritmatika, tergantung pada pilihan kami ("12345"), kemudian mencari ini dalam daftar digit yang disusun ulang. Kode sebenarnya dilemparkan ke karakter pertama dan kemudian menggantikan ordinals, tetapi juga dimungkinkan dalam 37 byte dengan karakter, misalnya "DIAAE" ( coba ).

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ - link: list of characters
 “RGS”                                - literal ['R','G','S']
ḟ                                     - filter discard
      O                               - convert to ordinals
       “OX‘                           - code-page indices list = [79,88]
            “¢©“¢¢¤‘                  - code-page indices lists = [[1,6],[1,1,3]]
           ,                          - pair -> [[79,88],[[1,6],[1,1,3]]]
                    y                 - translate (replace 79s (Os) with [1,6]
                                                       and 88s (Xs) with [1,1,3])
                     F                - flatten into a single list
                       4/             - 4-wise reduce by:
                      ×               -   multiplication (product of each window of four)
                         %74          - modulo 74
                                   ¤  - nilad followed by link(s) as a nilad:
                             ⁽G×      -   base 250 literal = 18768
                                œ?9   -   permutation of [1,2,3,4,5,6,7,8,9] at that
                                      -   index in a lexicographically sorted list of
                                      -   all such permutations -> [1,5,8,2,4,9,7,6,3]
                            ị         - index into
                                    Ḍ - convert from decimal digits to an integer
Jonathan Allan
sumber
Jawaban Anda secara harfiah satu-satunya jawaban pada halaman ini yang mengembalikan nilai yang benar untuk: NINEONENIENOENNNIENOENNEINEONEINEONNENIENOINNEINENINNEINENIENNIENNNNIENNEININENIENNENINEINENINENNIEINNEINNENNIENIN.
Magic Gurita Guci
+ Poin Infinity.
Magic Gurita Guci
Terima kasih! (yang melemparkan saya karena tidak ada spasi lebar nol untuk blok kode dalam komentar, tetapi (wah) itu berhasil )
Jonathan Allan
Itu bukan input yang valid;).
Magic Octopus Mm
Oh wow, saya tidak tahu hadiah akan datang - terima kasih! Ya, itu bukan bagian dari spesifikasi yang diminta, saya hanya membuat metode yang akan bekerja dengan input yang tidak terurut.
Jonathan Allan
10

Python 2, 121 117 115 byte

def g(s,a=0,f=''):
 for c in s:
    a+=34**ord(c)%43;r='P!\x83u\x8eI\x92|Z'.find(chr(a))+1
    if r:f,a=f+`r`,0
 return f

-4 bytes: Lagipula golf itu saya lupa sebariskan variabel sekali pakai. Kentut otak.
-2 byte: Indentasi spasi ganda → indentasi tab tunggal (terima kasih kepada Coty Johnathan Saxman); perhatikan bahwa ini tidak ditampilkan dengan benar dalam jawaban.

Tidak disatukan (kompatibel dengan python 3):

nums = [80, 33, 131, 117, 142, 73, 146, 124, 90]

def decode(str):
    acc = 0
    final = ''
    for c in str:
        acc += (34**ord(c))%43
        if acc in nums:
            final += str(1+nums.index(acc))
            acc=0
    return final

Pencari angka ajaib:

#!/usr/bin/env python3
from itertools import count, permutations

def cumul(x):
    s = 0
    for v in x:
        s += v
        yield s

all_words = 'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()

for modulo in range(1, 1000):
    for power in range(1, 300):
        combinations = []
        for word in all_words:
            my_combination = []
            for perm in permutations(word):
                my_combination += cumul(power**(ord(x)) % modulo for x in perm)
            combinations.append(my_combination)

        past_combinations = set(())
        past_intermediates = set(())
        collision = False
        for combination in combinations:
            final = combination[-1]
            if final in past_intermediates or any(intermediate in past_combinations for intermediate in combination):
                collision = True
                break
            past_combinations.add(final)
            past_intermediates.update(combination)

        if not collision:
            print("Good params:", power, modulo)
            print("Results:", ", ".join(str(x[-1]) for x in combinations))

Penjelasan:

Saya punya perasaan bahwa saya bisa menghancurkan bit ASCII bersama-sama dan merangkumnya entah bagaimana untuk menentukan kapan saya memiliki kata penuh. Awalnya saya mencoba mengotak-atik 3**ord(letter)dan membandingkan dengan hasil yang diharapkan, tetapi menghasilkan beberapa angka yang sangat besar. Saya pikir itu akan tepat untuk memaksa beberapa parameter sedikit, yaitu modulus (untuk memastikan jumlahnya kecil) dan pengganda untuk menyebarkan angka secara berbeda di sekitar kisaran modulus.

Saya akhirnya mengubah variabel pengali menjadi variabel yang mempengaruhi daya itu sendiri karena (dari coba-coba) yang entah bagaimana berhasil memberi saya jawaban golf yang sedikit lebih pendek.

Dan di atas Anda melihat hasil dari kekerasan itu dan sedikit bermain golf secara manual.

Alasan memilih 3**xawalnya adalah karena saya tahu Anda bisa mewakili setiap nomor di sana. Digit yang paling sering diulangi oleh angka apa pun adalah dua (thrEE, sEvEn, NiNe, dll), jadi saya memutuskan untuk menganggap setiap input sebagai nomor basis-3. Dengan cara itu saya dapat (secara mental) merepresentasikan mereka sebagai sesuatu seperti 10100000000010020000(tiga; a 1 di tslot, 1 di rslot, 1 di hslot, dan 2 di eslot). Setiap angka dengan cara ini mendapatkan representasi unik yang dapat dengan mudah disatukan dengan iterasi string dan menjumlahkan beberapa angka, dan akhirnya independen dari urutan huruf yang sebenarnya. Tentu saja, ini tidak menjadi solusi yang ideal, tetapi solusi saat ini masih ditulis dengan pemikiran ini.

Score_Under
sumber
Apa itu Py3K? ...
CalculatorFeline
Permintaan maaf, diedit (itu adalah nama mantan python 3)
Score_Under
1
Itu murah, tetapi Anda dapat menyimpan 2 byte (karena ini adalah python 2) dengan menundukkan tingkat lekukan kedua Anda (dua spasi) untuk satu tab. [ tio.run / ##NU7NCoJAGDy7T/... Cobalah secara online!]
Coty Johnathan Saxman
Juga, Anda mungkin dapat menyimpan 6 byte menggunakan literal \x83, \x8edan \x92dalam string.
CalculatorFeline
@CalculatorFeline Sayangnya penerjemah saya tidak seperti itu: SyntaxError: Non-ASCII character '\xc2' in file <stdin> on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details. Ini berfungsi jika saya menaruh codingkomentar di sana, tetapi itu mendapatkan 15 byte tambahan.
Score_Under
6

Python 2 , 131 127 byte

s=input()
for y in'WXGURFSOIZ':vars()[y]=s.count(y)
while Z<9:s+=[O-U-W,W,R-U,U,F-U,X,S-X,G,I-X-G-F+U][Z]*str(Z+1);Z+=1
print s

Cobalah online!

Berdasarkan versi yang diperbaiki dari solusi JavaScript Draco18s .

mdahmoune
sumber
Penggunaan yang sangat menarik vars!
xnor
@ xnor itu adalah bagaimana belajar saya untuk golf lain :)))
mdahmoune
Sangat pintar. Miliki +1 untuk mengadaptasi jawaban saya (sama cacatnya seperti aslinya).
Draco18s
5

PHP , 164 byte

for($c=count_chars($argn);$i<9;)echo str_pad("",[$c[79]-$c[87]-$u=$c[85],$c[87],$c[72]-$g=$c[71],$u,$f=$c[70]-$u,$x=$c[88],$c[86]-$f,$g,$c[73]-$x-$f-$g][+$i],++$i);

Cobalah online!

PHP , 179 byte

berdasarkan pendekatan sebelumnya periksa terlebih dahulu angka genap dan kemudian angka ganjil dalam urutan meningkat

for($z=[$o=($c=count_chars($argn))[87],$f=$c[85],$x=$c[88],$g=$c[71],$c[79]-$o-$f,$c[72]-$g,$v=$c[70]-$f,$c[86]-$v,$c[73]-$x-$v-$g];$i<9;)echo str_repeat(++$i,$z[_405162738[$i]]);

Cobalah online!

PHP , 201 byte

for(;$o=ord(WUXGOHFVN[$i]);$i++)for(;$r[$o]<count_chars($argn)[$o];$t[]=$i>3?2*$i-7:2+2*$i,sort($t))for(++$r[$o],$n=0;$q=ord(([TO,ORF,IS,HEIT,EN,TREE,IVE,SEEN,NIE][+$i])[$n++]);)$r[$q]++;echo join($t);

Cobalah online!

Jörg Hülsermann
sumber
gagal untukENOOWTWTOWOT
Titus
@Titus sekarang sudah diperbaiki. Saya salah paham pertanyaan
Jörg Hülsermann
Ya contohnya agak menyesatkan. Wow itu memang biaya! Apakah Anda akan memecahnya ?!
Titus
@Itus saya pikir saya telah mencapai batas untuk menemukan cara lain sebagai pendekatan Anda
Jörg Hülsermann
1
$i++<9dan $ibukannya $i<10dan ++$i(-1 byte); _405162738[$i]bukannya $i%2?$i/2+4:$i/2-1(-4 byte) ( $i/2+~($i%2*-5)akan bekerja juga, tapi itu satu byte lebih lama.)
Titus
5

Javascript (ES6), 288 150 144 byte

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, q(testCase)))

Lebih lama dari dua entri JS lainnya, tapi saya pikir saya akan menjatuhkan pendekatan yang menarik yang mungkin bekerja untuk seseorang dalam bahasa lain.

Pada dasarnya kita dapat menentukan hal berikut:

W -> 2
X -> 6
G -> 8
U -> 4

Kemunculan huruf-huruf ini menyiratkan bahwa digit itu ada di nomor aslinya. Dari sini kita dapat menyimpulkan sisa digit:

R-U -> 3
F-U -> 5
S-X -> 7

Termasuk dua kasus rumit:

O-(U+W) -> 1
I-(X+G+(F-U)) -> 9

Baik 1dan 9daerah Sulit relatif. Untuk SATU, Emuncul lebih dari sekali dalam beberapa kata ( SEVENmemiliki dua) seperti halnya N( NINE), jadi kami terjebak dengan pemeriksaan Oyang terjadi di dua tempat lain, untungnya keduanya sederhana.

Bagi SEMBILAN, sembilan sulit tidak masalah bagaimana Anda mengirisnya.

Jadi kita berakhir dengan peta ini:

[u=(l=t=>s.split(t).length-1)`U`,  //unused 0; precompute 'U's
 l`O`-l`W`-u,    //1
 l`W`,           //2
 l`R`-w,         //3
 u,              //4
 f=l`F`-u,       //5
 x=l`X`,         //6
 l`S`-x,         //7
 g=l`G`,         //8
 l`I`-x-g-f]     //9

9 dapat melakukan back-reference siX, eiGht, dan Five (dengan 5 back-referencing untuk) dengan penugasan variabel, menghemat byte. Berkat Neil untuk ini, ia menggunakan beberapa fitur JS Saya sangat tidak terbiasa dengan (tanda centang untuk pengupasan menjadi ('dua, misalnya) dan benar-benar datang lebih dekat dengan ide saya mencoret-coret di atas kertas sebelum mencoba untuk kode itu (Saya meninggalkan 9 sebagai "apa yang tersisa", memikirkannya sebagai "jika saya melihat Xsaya dapat menghapusnya dan Sdan dan Idari string, maka ..." sehingga setelah empat kasus sederhana 3 berikutnya akan menjadi sederhana).

Alasan entri ini menarik adalah karena dapat menangani string yang dikocok sebagai input. yaitu, alih-alih kata-kata individual yang dikocok, kita dapat mengocok seluruh string, yang menurut saya awalnya dilakukan John:

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['XENSENINEVSI']

testCases.forEach(testCase => console.log(testCase, q(testCase)))

Draco18s
sumber
1
Hebat, tetapi ada masalah dengan penghitungan 9 ... Saya pikir itu mungkin ixg-f + u
mdahmoune
@mdahmoune Tembak, kau benar. Saya mengacaukan yang satu itu. : <
Draco18s
Simpan 4 byte dengan menggunakan s.split(t).length-1, 2 byte menggunakans.repeat(n>0&&n) (mengapa n masih kurang dari nol? Menyimpan 7 byte). Simpan banyak byte dengan mendeklarasikan gdalam ruang lingkup ssehingga Anda tidak harus terus melewatinya, dan lebih baik lagi Anda bisa menjadikannya sebagai tagged template, yang menyimpan total 55 byte (sebelum 9 koreksi). Simpan lebih byte dengan menyimpan nilai-nilai diulang dalam temporaries, dan saya mencukur beberapa off menggunakan map: s=>[,(l=t=>s.split(t).length-1)`O`-l`W`-l`U`,w=l`W`,l`R`-w,u=l`U`,l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g].map((n,i)=>`${i}`.repeat(n)).join`` .
Neil
@ Neil Saya tidak yakin mengapa N pernah berakhir kurang dari nol, tapi itu saat menguji untuk TIGA. Saya terus mendapatkan kesalahan dan menyelidiki bahwa itu diperlukan, tetapi saya masih tidak yakin. Peta perpustakaan templated yang Anda punya di sana adalah javascript yang bahkan tidak saya baca. : D
Draco18s
@ Neil Ah, benar, alasan untuk memeriksa n> 0: Jika ada adalah sebuah DUA tetapi tidak ada TIGA. R = 0, W = 1. 0-1 = -1. Saya mengalami kesulitan mencari tahu itu satu jam yang lalu, saya tahu bahwa itu terkait dengan cek 3, tetapi memiliki setan waktu mengerjakannya (kekurangan kopi).
Draco18s
4

Mathematica, 133 byte

(s={};c=Characters;j=c@#;Table[If[FreeQ[j~Count~#&/@c[#[[i]]]&@ToUpperCase@IntegerName@Range@9,0],s~AppendTo~i],{i,9}];FromDigits@s)&


memasukkan

"VENESGTHIEENNI"

keluaran

789

J42161217
sumber
Bisakah Anda menyimpan byte tambahan dengan c@#[[i]]bukan c[#[[i]]]? Anda mungkin dapat menyimpan byte lain dengan menggunakan sintaks infix ~pada Table.
numbermaniac
4

C #, 218 byte

Versi pendek:

string q(string s){var n="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');for(inti=0,j;;i++)for(j=0;n[i].IndexOf(s[j])>=0;){if(++j==n[i].Length){var r=++i+"";for(;j<s.Length;r+=++i)j+=n[i].Length;return r;}}}

Versi yang diperluas:

string q(string s)
{
    var n = "ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');
    for (int i = 0, j; ; i++)
        for (j = 0; n[i].IndexOf(s[j]) >= 0;)
        {
            if (++j == n[i].Length)
            {
                var r = ++i + "";
                for (; j < s.Length; r += ++i)
                    j += n[i].Length;
                return r;
            }
        }
}

Coba ONLINE!

Menjadi entri pertama saya, saya tidak yakin tentang aturan ... Saya hanya menghitung ukuran kelas yang digunakan untuk de-crypt, bukan kode yang mengujinya, kan?

Edit

Dan untuk bersenang-senang - inilah yang saya mulai lakukan, tidak membaca aturan lengkap: S - Lihat di IdeOne . Itu de-crypts bahkan ketika karakter dari satu digit dapat diacak ke setiap tempat di string.

Edit 2

Disingkat menurut tips oleh TheLethalCoder. Terima kasih!

Edit 3

Dan sekarang Titus mencukur beberapa byte lagi. Terima kasih!

SamWhan
sumber
2
Halo dan selamat datang di PPCG! Anda hanya perlu memasukkan metode, Anda dapat menghapusnya public static. Anda dapat mengonversi ke metode anonim seperti s=>{<do stuff>return"";}. Anda dapat menggunakan varbeberapa kali, mendeklarasikan variabel secara bersamaan menghemat byte int i=1,j;. Membuat array dari string dan membelahnya biasanya lebih pendek (meskipun saya belum memeriksa dalam kasus ini) yaitu "ONE|TWO".Split('|'). Anda dapat menggunakan <0sebagai gantinya==-1
TheLethalCoder
Untuk tips lainnya, lihat Tip untuk bermain golf kode di C # .
TheLethalCoder
@TheLethalCoder Kiat-kiat hebat, terima kasih!
SamWhan
Tidak diuji sama sekali tetapi saya percaya yang berikut ini adalah setara dengan kode Anda untuk 221 byte:s=>{var n="ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE".Split('|');for(int i=0,j;++i<= 9;)for(j=0;n[i-1].IndexOf(s[j])<0;){if(++j==n[i-1].Length){var r=i+"";while(j<s.Length){j+=n[i].Length;r+=++i;}return r;}}return "";}
TheLethalCoder
Sebagai catatan, biasanya lebih mudah untuk menggunakan TIO untuk TIO Anda!
TheLethalCoder
3

JavaScript (ES6), 142 139 Bytes

Disimpan 3 Bytes berkat Neil .

Saat ini tidak memanfaatkan angka yang selalu diatur dalam urutan menaik

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, f(testCase)))

Craig Ayre
sumber
tunggu apa?? "axbxc".split`x`.join``. Bagaimana ini disebut? Tampaknya tidak dapat menemukan apa pun di google.
Qwerty
@Qwerty - Mereka menandai templat literal , fitur ES6 yang saya gunakan untuk menyimpan beberapa byte dengan tidak memerlukan parens dalam kasus splitdanjoin
Craig Ayre
Anda menjawabnya. Saya tahu tag templat literal, tapi saya belum sadar Anda bisa menggunakannya pada fungsi-fungsi ini juga. Terima kasih.
Qwerty
Mereka sedikit berbeda, Anda memiliki templat literal (misalnya x=`foo${5+5}bar`), mereka ditandai ketika Anda memanggil fungsi menggunakan mereka tanpa parens: foo`foo${5+5}bar`yang sama denganfoo(['foo','bar'], 10)
Craig Ayre
1
f(s.slice(y))selalu merupakan string sehingga Anda tidak perlu ''+sebelumnya.
Neil
2

Jelly , 38 byte

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu
L3*Ç€iṢ

Cobalah online!

Penjelasan

L3*Ç€iṢ    Main link. Argument: s (string)
L            Get length of s.
 3*          Raise 3 to that power. This will always be greater than n.
   ǀ        Get the name of each of the numbers using the helper link.
     iṢ      Find the position of the sorted input.

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu    Helper link. Argument: n (number)
D                                   Get digits of n.
  “©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»            The string "one two (...) eight nine AA".
                        Ḳ           Split that string at spaces.
 ị                                  Get name of each digit in the list.
                          F         Flatten to a single string.
                           Ṣ        Sort the characters.
                            Œu      Make uppercase.
PurkkaKoodari
sumber
Ada masalah dengan kode Anda. Coba "EIGHTNINE"
masukkan
@Amorris diperbaiki untuk 0 byte.
PurkkaKoodari
Saya pikir itu tidak bekerja untuk "VENESGTHIEENNI"
J42161217
Saya kedua @Jenny_mathy
Amorris
@ Jenny_mathy Program ini sangat tidak efisien dan kehabisan waktu dan memori untuk input lama (saya tahu, itu benar-benar buruk). Anda dapat mengganti 3dengan 2.2menggunakan batas atas yang lebih kecil, yang memungkinkan Anda untuk menghitung 789 dengan mudah tanpa mengubah prinsip kerja. 2akan menyenangkan, tetapi hampir tidak akan gagal untuk input tertentu dengan banyak enam.
PurkkaKoodari
2

Javascript (ES6), 221 byte

s=>(m=btoa`8Ñ>Mc¾LtDáNQ!Q>HþHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

Cuplikan kode contoh:

f=

s=>(m=btoa`8Ñ>Mc¾LtDáNQ…!Q>H…þHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

console.log(f("NEO"))
console.log(f("ENOWOT"))
console.log(f("EONOTWHTERE"))
console.log(f("SNVEEGHEITNEIN"))
console.log(f("ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN"))

Herman L.
sumber
2

Retina , 160 byte

([ONE]{3})*([TWO]{3})*([THRE]{5})*([FOUR]{4})*([FIVE]{4})*([SIX]{3})*([SEVN]{5})*([EIGHT]{5})*([NIE]{4})*
$#1$*1$#2$*2$#3$*3$#4$*4$#5$*5$#6$*6$#7$*7$#8$*8$#9$*9

Cobalah online! Secara longgar didasarkan pada jawaban PowerShell @ TessellatingHeckler.

Neil
sumber
2

Retina , 88 byte

[EFIST]

^(ON|NO)*
$#1$*1
O

W
2
HR|RH
3
UR|RU
4
X
6
GH|HG
8
(NN)*$
$#1$*9
r`NV|VN
7
V
5

Cobalah online!

Penjelasan

  • Pertama, letakkan sekelompok karakter yang tidak perlu yang tidak diperlukan untuk perbedaan
  • Pilih 1s dari depan (ini memungkinkan kita menjatuhkan sisa Os segera setelah dan membersihkan beberapa Ns sebelum kita sampai ke kekacauan 5, 7, 9)
  • 2, 3, 4, 6, dan 8 sekarang sepele
  • Angka 9 adalah NN ganda, jadi ambil angka tersebut sebelum kita membahas angka 5 dan 7
  • Ganti 7s dari kanan (jadi kami tidak mengurangi VNV menjadi 75 bukannya 57)
  • 5s adalah Vs yang tersisa
Kytheron
sumber
Jika Anda menambahkan% (G` ke tajuk, Anda dapat menggunakan kode asli dan akan mengevaluasi setiap baris input secara terpisah: TIO
PunPun1000
Terima kasih @ PunPun1000. Saya pikir pasti ada cara untuk melakukan itu tetapi menyerah setelah tidak menemukannya dengan cepat.
Kytheron
1

PowerShell , 182 byte

[regex]::Replace("$args",'(?<1>[ONE]{3z2>[TWO]{3z3>[THRE]{5z4>[FOUR]{4z5>[FIVE]{4z6>[SIX]{3z7>[SVEN]{5z8>[EIGHT]{5z9>[NIE]{4})'.replace('z','})|(?<'),{$args.groups.captures[1].name})

Cobalah online!

Kode tidak dikerjakan tetapi tidak berfungsi:

[System.Text.RegularExpressions.Regex]::Replace("$args",

    '(?<1>[ONE]{3})       
    |(?<2>[TWO]{3})
    |(?<3>[THRE]{5})
    |(?<4>[FOUR]{4})
    |(?<5>[FIVE]{4})
    |(?<6>[SIX]{3})
    |(?<7>[SVEN]{5})
    |(?<8>[EIGHT]{5})
    |(?<9>[NIE]{4})'

    ,{$args.groups.captures[1].name}
)

misalnya (?<3>[THRE]{5})cocok dengan kelas karakterTHRE , sehingga dapat cocok dengan mereka di luar urutan, dan harus mencocokkan salah satu dari karakter ini lima kali bersebelahan, dan grup tangkap bernama '3' untuk memetakan nama dengan angka.

Kompresi yang belum sempurna dengan menukar teks berulang })|(?<untuk a z.

TessellatingHeckler
sumber
1

C ++, 296 , 288 byte

Versi pendek:

#define T string
using namespace std;T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};T Q(T S){T R="";for(int i=0;i<9;i++){do{if(S.find(N[i])!=T::npos){S.erase(S.find(N[i]),N[i].size());R+=to_string(i+1);}}while(next_permutation(N[i].begin(),N[i].end()));}return R;}

Versi lengkap:

#define T string
using namespace std;

T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};

T Q(T S)
{
    T R="";
    for(int i=0;i<9;i++)                             //for all possible                             
                                                     //codewords (ONE,TWO...NINE)   
    {
        do
        {   
            if(S.find(N[i])!=T::npos)                //if found in encrypted word
            {
                S.erase(S.find(N[i]),N[i].size());  //erase it from the word
                R+=to_string(i+1);                  //save integer to the result string
            }
                                                    //check next permuation of codeword  

        } while(next_permutation(N[i].begin(),N[i].end())); 
    }                                                   

    return R;
}

Coba ONLINE!

Sunting:
1) 200-> 296 byte, untuk memasukkan namespace dan definisi N dalam hitungan, seperti yang disarankan oleh orlp 2) 296-> 288, untuk menggunakan makro, terima kasih kepada Zacharý

koita_pisw_sou
sumber
Anda harus memasukkan definisi Ndan using namespace std;ke dalam jumlah byte Anda.
orlp
Saya harus lebih spesifik, tidak hanya memasukkannya dalam hitungan byte Anda tetapi juga ke dalam jawaban Anda. Jawaban Anda harus dapat dijalankan hanya dengan menelepon Qtepat setelah itu tanpa tambahan lainnya.
orlp
Saya diedit ulang untuk memasukkan semuanya. Untuk definisi N saya sendiri tidak yakin, tetapi untuk namespace, saya biasanya tidak memasukkannya (memperlakukannya sebagai barang perpustakaan). Padahal, dalam kode saat ini sangat penting untuk string untuk bekerja
koita_pisw_sou
1
Bisakah Anda mendefinisikan makro untuk menyimpan beberapa byte? repl.it/JY7k
Zacharý
1

Ruby, 138 114 110 byte

gsub(/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/){(1..9).find{|i|$~[i]}}

Hitungan byte mencakup 1 byte untuk -popsi.

Apa?

Ini:

/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/

adalah regex literal yang, melalui interpolasi string, mengevaluasi untuk:

/([ONE]{3})|([TWO]{3})|([THRE]{5})|([FOUR]{4})|([FIVE]{4})|([SIX]{3})|([SEVN]{5})|([EIGHT]{5})|([NIE]{4})|/

Jika kita menetapkan itu untuk regex, sisa kode agak mudah untuk dipahami: Setiap kecocokan dalam input diganti dengan jumlah kelompok penangkap, diekstraksi dari variabel magis $~yang berisi data pencocokan saat ini:

gsub(regex){(1..9).find{|i|$~[i]}}

Cobalah online!

daniero
sumber
1

Java 8, 198 256 byte

s->{String r="",x=r;for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){for(char c:n.toCharArray())x+="(?=.*"+c+")";x+="["+n+"]{"+n.length()+"}x";}for(int i=0,q;i<9;)for(q=(s+" ").split(x.split("x")[i++]).length-1;q-->0;)r+=i;return r;}

+58 byte .. karena regex dari versi sebelumnya tidak berfungsi dengan baik (itu juga cocok dengan "EEE"; "EEN"; dll.)

Penjelasan:

Coba di sini.

s->{                     // Method with String as parameter and return-type
  String r="",           //  Result-String
         x=r;            //  Regex-String
  for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){
                         //  Loop (1) from "ONE" through "NINE":
    for(char c:n.toCharArray())
                         //   Inner loop (2) over the characters of this String
      x+="(?=.*"+c+")";  //    Append regex-group `(?=\w*c)` where `c` is the capital character
                         //   End of inner loop (2) (implicit / single-line body)
    x+="["+n+"]{"+n.length()+"}x";
                         //   Append regex part `[s]{n}` where `s` is the String, and `n` is the length
  }                      //  End of loop (1)
  // The regex now looks like this, which we can split on "x":
  // (?=.*O)(?=.*N)(?=.*E)[ONE]{3}x(?=.*T)(?=.*W)(?=.*O)[TWO]{3}x(?=.*T)(?=.*H)(?=.*R)(?=.*E)(?=.*E)[THREE]{5}x(?=.*F)(?=.*O)(?=.*U)(?=.*R)[FOUR]{4}x(?=.*F)(?=.*I)(?=.*V)(?=.*E)[FIVE]{4}x(?=.*S)(?=.*I)(?=.*X)[SIX]{3}x(?=.*S)(?=.*E)(?=.*V)(?=.*E)(?=.*N)[SEVEN]{5}x(?=.*E)(?=.*I)(?=.*G)(?=.*H)(?=.*T)[EIGHT]{5}x(?=.*N)(?=.*I)(?=.*N)(?=.*E)[NINE]{4}x
  for(int i=0,q;i<9;)    //  Loop (3) from 0 through 9 (exclusive)
    for(q=(s+" ").split(x.split("x")[i++]).length-1;
                         //   Split the input on the current regex-part,
                         //   and save the length - 1 in `q`
        q-->0;           //   Inner loop (4) over `q`
      r+=i               //    And append the result-String with the current index (+1)
    );                   //   End of inner loop (4)
                         //  End of loop (3) (implicit / single-line body)
  return r;              //  Return the result-String
}                        // End of method
Kevin Cruijssen
sumber
1
Erf ... hasil salah untuk "ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN":(
Olivier Grégoire
Ya, itulah satu-satunya hal yang mencegah saya memberi ini +1! Solusi saya adalah 240 byte ... sebelum Anda mengalahkan saya untuk itu.
Olivier Grégoire
@ OlivierGrégoire Jangan ragu untuk memposting solusi 240 byte Anda, karena saya tidak dapat menemukan solusi .. Kerugiannya [ONE]{3}adalah bahwa ia juga cocok EENpada akhir test case dengan bagian EIGHT dan SEMBILAN .. Dan saya ragu ada sebuah regex untuk mencocokkan semua ini: ENO|EON|NEO|NOE|OEN|ONEtanpa juga cocok EEE;EEN;EEO;...untuk semua angka yang lebih pendek dari 40 byte .. Mungkin saya bisa melakukan sesuatu menggunakan substringdan membalikkan memeriksa angka, tapi saya tidak benar-benar punya waktu untuk mencari tahu sekarang ..
Kevin Cruijssen
@ OlivierGrégoire Jika Anda masih memiliki jawaban 240 byte, jangan ragu untuk mempostingnya. Baru saja menemukan tantangan ini lagi, dan memperbaiki jawaban saya dengan membuat regex baru untuk +58 byte ..
Kevin Cruijssen
1
Yah, sepertinya saya menemukan cara yang lebih pendek saat mengulangi tantangan ini: p
Olivier Grégoire
1

Java (OpenJDK 8) , 181 byte

s->{String x="",r;for(int i=0,l;i<9;)for(r="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".split(",")[i++],l=r.length();s.matches("["+r+"]{"+l+"}.*");s=s.substring(l))x+=i;return x;}

Cobalah online!

Saya mengambil kebebasan untuk menggunakan kembali template TIO Kevin Cruyssen . Semoga Anda tidak keberatan;)

Olivier Grégoire
sumber
Ah, nevermind komentar saya sebelumnya .. Anda membangun regex, bukan loop di atas regex. Tetap saja, saya sudah dekat dengan jawaban pertama saya kalau saja saya sudah menggunakan s.substring. Bagian terburuknya adalah, saya menggunakan s.substringjawaban saya saat ini, lol .. Ah well, +1 dari saya. Senang sudah hampir akhir pekan ..
Kevin Cruijssen
1

05AB1E , 36 31 byte

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#vyœN>UvyX:

Cobalah online!


Lihat itu dijalankan dengan debug: TIO Dengan Debug

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# | Push ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
vyœ                   | For each list of permutations of that word...
   N>U                | Push index + 1 into register X.          
      vyX:            | Replace each permutation with X.
Guci Gurita Ajaib
sumber
Saya hanya menyarankan Anda memiliki tanda hijau daripada saya dan saya melihat ada bug: FURONESEVpengembalian FUR1SEV:(
Jonathan Allan
1

Perl 5 , 102 + 1 (-n) = 103 byte

for$i(map{"[$_]{".length.'}'}ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE){$,++;print$,while(s/^$i//)}

Cobalah online!

Xcali
sumber
Bagus! Beberapa trik yang membantu: map{...}sering dapat diganti dengan map...,, lengthdan y///cbiasanya dipertukarkan juga (tidak selalu lebih kecil bila tidak bekerja pada $_meskipun!), Bukan while, ++$,x s/^$i//lebih pendek, dan jika Anda mengubah -nke -pAnda dapat menambahkan ke `$ \` bukan menelepon print! Cobalah online!
Dom Hastings
Juga, saya harap Anda tidak keberatan saya mengirim saran, jika Anda mau saya akan menahan diri. :)
Dom Hastings
0

Python 3 , 238 236 byte

def f(s):
 e=''
 while len(s):
  for i in range(9):
   for r in[''.join(p)for p in permutations('ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()[i])]: 
    if s[:len(r)]==r:e+=str(i+1);s=s[len(r):]
 return e
from itertools import*

Cobalah online!


Solusi brute-force, tidak memanfaatkan non-penurunan angka.


Terima kasih untuk @Mr. Xcoder untuk menghemat 2 byte!

Chase Vogeli
sumber
Anda harus memasukkan def f(s):dalam jumlah byte Anda, ini bukan fungsi anonymouos
Tn. Xcoder
Anda juga dapat menggantinya while len(s)>0denganwhile len(s)
Tn. Xcoder
@ Mr.Xcoder terima kasih atas klarifikasi itu
Chase Vogeli
Anda dapat memindahkan deklarasi eke dalam header fungsi untuk -1 byte. Juga, execdan daftar pemahaman mungkin menghemat byte pada indentasi.
CalculatorFeline
0

PHP, 141 byte

for($a=count_chars($argn);$c=ord($s[++$p]?:$s=[OWU,W,HG,U,FU,X,SX,G,N17.$p=0][$i-print str_repeat($i++,$x)]);)$x=$a[$i+48]+=($p?-1:1)*$a[$c];

versi yang lebih lama, 151 byte :

for($a=count_chars($argn,1);$s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];print str_repeat($i,$a[$i+48]))for($p=0;$c=ord($s[$p]);)$a[$i+48]+=($p++?-1:1)*$a[$c];

loop melalui digit dari 1 hingga 9, menghitung karakter unik dalam kata dan mengurangi jumlah karakter non-unik, mencetak digit saat bepergian.
Meskipun sedang mencetak saat bepergian, jumlah digit harus disimpan agar 9kasing berfungsi.

Jalankan sebagai pipa dengan -nRatau coba online .

Ini akan menghemat 4 byte lagi untuk menyimpan jumlah digit $a[$i]sebagai ganti $a[$i+48]dan menggunakan ASCII 1dan 7(dalam tanda kutip) alih-alih karakter digit itu sendiri.

kerusakan

for(
    $a=count_chars($argn,1);                # count character occurences in input
    $s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];   # loop through digit names
    print str_repeat($i,$a[$i+48])              # print digit repeatedly
)
    for($p=0;$c=ord($s[$p]);)                   # loop through name
        $a[$i+48]+=                                 # add to digit count
        ($p++?-1:1)*                                # (add first, subtract other)
        $a[$c];                                     # character occurences

ONEbukan satu-satunya kata dengan O, jadi ia harus mengurangi jumlah untuk W(hanya muncul di TWO) dan U(hanya muncul di FOUR) dan sebagainya.
NINEkhusus, karena tidak ada cara untuk mengurangi jika saya menggunakan huruf (yang akan membutuhkan I-X-G-F+Uatau N-O-S+W+U+X), jadi saya menggunakan jumlah digit sebagai gantinya.

PHP, 160 byte

$a=count_chars($argn);foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)for(${$s[$p=1]}+=$n=$a[ord($s)];$c=ord($s[++$p]);)$a[$c]-=$n;while($$i--?print$i:$i++<9);

mengasumsikan semua input huruf besar; karakter dapat diacak di seluruh.
Jalankan sebagai pipa dengan -nRatau coba online .

penjelasan

loop melalui kata-kata digit, menghitung kemunculan karakter unik mereka dalam input dan dalam proses mengurangi jumlah karakter lain. "Karakter lain" dapat berarti semua karakter lain dalam kata; tetapi hanya dengan mempertimbangkan yang akan dibutuhkan kemudian disimpan 19 byte.

Mengubah str_repeatloop ke loop gabungan disimpan 5 byte.

Dan menggunakan variabel variabel untuk jumlah digit disimpan 8 lainnya.

kerusakan

$a=count_chars($argn);                              # count character occurences in input
foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)   # loop through digit names
    for(${$s[$p=1]}+=                                   # 2. add to digits count
        $n=$a[ord($s)];                                 # 1. get count of unique character
        $c=ord($s[++$p]);)                              # 3. loop through other characters
        $a[$c]-=$n;                                         # reduce character count
while(
    $$i--?print$i                                       # print digit repeatedly
    :$i++<9);                                       # loop through digits
Titus
sumber