Kalkulator Numerologi

19

Tujuan dari tantangan ini adalah untuk menghitung satu jenis angka numerologi dari string yang berisi karakter dan angka.

  • Input dapat melalui metode apa pun yang nyaman (input standar, argumen, file terpisah).
  • Input dapat mengandung karakter ASCII dicetak, tetapi hanya alfanumerik ( A-Z, a-z, dan 0-9) harus dipertimbangkan.
  • Outputnya harus berupa digit antara 1dan 9atau bintang *jika tidak ada huruf dan tidak ada digit di mana ditemukan ... (atau bahkan 0jika input berisi sejumlah 0 dan tidak ada yang lain tetapi ini tidak masalah).
  • Nilai huruf dipetakan dengan cara ini:

    1  2  3  4  5  6  7  8  9
    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
    
  • The numerologi digit dihitung dengan menambahkan setiap nilai string, kemudian ulangi sampai hanya ada satu digit. Sampel untuk 13579, Hello, world!, 00 0 00, !@#$%^&*();, dan 3.141592:

    13579 => 1 + 3 + 5 + 7 + 9 = 25 => 2 + 5 = 7
    Hello, world! => 8 + 5 + 3 + 3 + 6 + 5 + 6 + 9 + 3 + 4 = 52 => 5 + 2 = 7
    00 0 00 => 0 + 0 + 0 + 0 + 0 = 0
    !@#$%^&*(); => *
      => *
    3.141592 => 3 + 1 + 4 + 1 + 5 + 9 + 2 = 25 => 2 + 5 = 7
    3.1415926535897932384 => 
     3 + 1 + 4 + 1 + 5 + 9 + 2 + 6 + 5 + 3 + 5 + 8 + 9 + 7 + 9 + 3 + 2 + 3 + 8 + 4
     = 97 => 9 + 7 = 16 => 1 + 6 = 7
    

    (Ini hebat, sebagian besar sampel ini memberi 7! Tapi itu hanya sampel;)

    Beberapa tes lagi:

    Bob  => 2 + 6 + 2 = 10 => 1 + 0 = 1
    Charlie => 3 + 8 + 1 + 9 + 3 + 9 + 5 = 38 => 3 + 8 = 11 => 1 + 1 = 2
    Anna => 1 + 5 + 5 + 1 = 12 => 1 + 2 = 3
    Fana => 6 + 1 + 5 + 1 = 13 => 1 + 3 = 4
    Gregory => 7 + 9 + 5 + 7 + 6 + 9 + 7 = 50 => 5 + 0 = 5
    Denis => 4 + 5 + 5 + 9 + 1 = 24 => 2 + 4 = 6
    Erik => 5 + 9 + 9 + 2 = 25 => 2 + 5 = 7
    Helen => 8 + 5 + 3 + 5 + 5 = 26 => 2 + 6 = 8
    Izis => 9 + 8 + 9 + 1 = 27 => 2 + 7 = 9
    

Ini adalah , jadi jawaban tersingkat dalam byte menang.

Singkat menurut bahasa

F. Hauri
sumber
0 akan hilang ketika ditambahkan ke hal lain
F. Hauri
0 tidak relevan! Output yang relevan adalah antara 1dan 9!
F. Hauri
Bisakah Anda menambahkan beberapa contoh tanpa karakter alfanumerik?
Produksi ETH
1
Maksud saya sesuatu seperti !@#$%^&*(); sesuatu yang harus kembali *.
ETHproduksi
Sangat sulit untuk menolak mengutip ini dalam beberapa diskusi analisis-teknis pada bidang Uang ... ;-p
keshlam

Jawaban:

6

Matlab, 121 byte

s=[input('','s'),'*'];while nnz(s)>1;s=num2str(sum(mod([s(48<s&s<58)-4,s(96<s&s<123)+2,s(64<s&s<91)-2],9)+1));end;disp(s)

Matlab tidak dibuat untuk string = (

cacat
sumber
3
Hei, setidaknya tidak
seterbuka
+1 saya, saya tidak bisa berbuat lebih baik. btw, apakah perlu memberikan disppernyataan?
brainkz
@brainkz Mungkin, tapi saya biasanya memasukkannya ke sisi yang aman
flawr
3

Mathematica, 174 168 163 byte

Catch[#-9Floor[Max[#-1,1]/9]&@If[(a=Tr[Characters@#/.{(b=a_String)?DigitQ:>FromDigits@a,b?LetterQ:>LetterNumber@a~Mod~9,b->0}])<1&&#~StringFreeQ~"0",Throw@"*",a]]&

Lakukan langkah pertama, lalu hitung root digital.

LegionMammal978
sumber
3

Ruby, 97 74 karakter

n=->s{(t=eval s.tr('a-z9A-Z','1-9'*6).scan(/\d/)*?+)&&t>9?n[t.to_s]:t||?*}

Contoh dijalankan:

2.1.5 :001 > n=->s{(t=eval s.tr('a-z9A-Z','1-9'*6).scan(/\d/)*?+)&&t>9?n[t.to_s]:t||?*}
 => #<Proc:0x00000001b4b3f0@(irb):4 (lambda)> 

2.1.5 :002 > puts ['13579', 'Hello, world!', '00 0 00', '!@#$%^&*();', ' ', '3.141592', '3.1415926535897932384', 'Bob', 'Charlie', 'Anna', 'Izis'].map{|s|'%s : %s'%[n[s],s]}
7 : 13579
7 : Hello, world!
0 : 00 0 00
* : !@#$%^&*();
* :  
7 : 3.141592
7 : 3.1415926535897932384
1 : Bob
2 : Charlie
3 : Anna
9 : Izis
manatwork
sumber
3

Perl, 91 89 76 74 byte

73 +1 untuk -p sakelar

s/[a-z]/(ord($&)%32-1)%9+1/eig;$t="*",s/\d/$t+=$&/eg,$_=$t until/^[*\d]$/

Tes

for test in '13579' 'Hello, world!' '00 0 00' '!@#$%^&*();' ' ' \
    '3.141592' '3.1415926535897932384' \
    Bob Charlie Anna Fana Gregory Denis Erik Helen Izis ;do  
    perl -pe '
      s/[a-z]/(ord($&)%32-1)%9+1/eig;$t="*",s/\d/$t+=$&/eg,$_=$t until/^[*\d]$/
      ' < <(echo -n "$test")
    echo "  $test"
done
7  13579
7  Hello, world!
0  00 0 00
*  !@#$%^&*();
*   
7  3.141592
7  3.1415926535897932384
1  Bob
2  Charlie
3  Anna
4  Fana
5  Gregory
6  Denis
7  Erik
8  Helen
9  Izis

Terima kasih @manatwork karena membantu saya menyelamatkan 2 14 16 15 17 karakter !!

... Saya sudah memikirkan: N % 32 + Ydapat menggantikan( N & 31 ) + Y !

F. Hauri
sumber
1
Jika Anda menangkap seluruh substring yang cocok, $1sama dengan $&. Jadi, lebih baik hapus penangkapan dan ubah nama variabel.
manatwork
1
whileMungkin blok itu $t="*";s/\d/$t+=$&/eg;$_=$t.
manatwork
1
Maaf, tetapi sebenarnya 1 karakter lebih panjang, karena Anda harus memasukkan -psakelar dalam hitungan.
manatwork
1
Maaf lagi (kali ini maaf lebih besar), tetapi gagal pada input karakter non-kata tunggal, misalnya "!" Menghasilkan yang sama "!". ( Tampaknya bekerja karena dengan di sini-string input selalu dilewati dengan baris tambahan, jadi dalam kasus uji Anda tidak pernah melewati input karakter tunggal. Gunakan echo -n "$test" | perl -pe '…'untuk melihat apa yang saya maksud.) Anda dapat menyelesaikannya dengan mengubah whilekondisi ke !/^[\d*]$/. Sementara di sana, untuk mengurangi kerugian skor, Anda mungkin mengganti seluruh whiledengan ini: $t="*",s/\d/$t+=$&/eg,$_=$t until/^[\d*]$/.
manatwork
1
Ada satu lagi peningkatan yang bisa Anda lakukan. Karena &memiliki prioritas lebih rendah daripada +, sementara %lebih tinggi, ubah &31%32dan Anda dapat menghapus tanda kurung di sekitar subekspresi itu.
manatwork
3

ES6, 98 byte

s=>(m=s.match(/[1-9a-z]/gi))?(t=8,m.map(c=>t+=c>'@'?c.charCodeAt()&31:+c),t%9+1):/0/.test(s)?0:'*'

Tidak Disatukan:

function(s) {
    var m = s.match(/[1-9a-z]/gi);
    if (m) {
        var t = 0;
        for (var i = 0; i < m.length; i++) {
            if (m[i] > '@')
                t += m[i].charCodeAt(0) & 31;
            else
                t += parseInt(m[i]);
        }
        return t % 9 || 9;
    }
    return /0/.test(s) ? 0 : "*";
}

Versi 94-byte yang hanya berfungsi pada string pendek:

s=>(m=s.match(/[1-9a-z]/gi))?m.map(c=>c>'@'?c.charCodeAt()&31:c).join``%9||9:/0/.test(s)?0:'*'

Menggunakan match, mapdan jointernyata lebih pendek daripada menggunakan replacedua kali:

s=>(m=s.replace(/[^1-9a-z]/gi,''))?m.replace(/[a-z]/gi,c=>c.charCodeAt()&31)%9||9:/0/.test(s)?0:'*'

Uji di sini: https://jsbin.com/zizosayisi/edit?js,console

Neil
sumber
Ini tidak berfungsi untuk input00 0 00
rink.attendant.6
@ rink.attendant.6 Ah, REPL saya hanya menggunakan sidik jari ["0"]sebagai 0jadi saya tidak bisa membedakannya.
Neil
Jauh, jauh lebih baik daripada versi @ rink.attendant.6! Retas golf pintar digunakan. Bisakah Anda jelaskan > '@', & 31dan || 9?
Pavlo
1
@Pavlo > '@'hanya membedakan antara huruf dan angka. & 31adalah cara yang bermanfaat untuk mengabaikan perbedaan antara kode karakter huruf besar dan kecil, karena juga secara langsung memetakan kode karakter ke dalam nilai 1..26. || 9digunakan karena % 9mengembalikan 0 untuk kelipatan 9 tetapi berulang kali menambahkan angka mengembalikan 9 untuk kelipatan bukan nol dari 9. Dalam kode golf saya menggunakan (t + 8) % 9 + 1sebaliknya yang datang ke hal yang sama.
Neil
Bahasa ini biasanya bernama "JavaScript (ES6)"
edc65
2

Gema, 161 karakter

*=@n{*}
n:\A=@set{t;};<L1>=@set{t;@add{$t;@add{@mod{@sub{@mod{@char-int{$0};32};1};9};1}}};<D1>=@set{t;@add{$t;$0}};?=;\Z=@cmps{$t;;;\*;@cmpn{$t;9;$t;$t;@n{$t}}}

(Ditulis hanya untuk mencoba apakah panggilan domain rekursif berfungsi.)

Contoh dijalankan:

bash-4.3$ for input in '13579' 'Hello, world!' '00 0 00' '!@#$%^&*();' ' ' '3.141592' '3.1415926535897932384'; do
>     echo -n "'$input' : "
>     gema '*=@n{*};n:\A=@set{t;};<L1>=@set{t;@add{$t;@add{@mod{@sub{@mod{@char-int{$0};32};1};9};1}}};<D1>=@set{t;@add{$t;$0}};?=;\Z=@cmps{$t;;;\*;@cmpn{$t;9;$t;$t;@n{$t}}}' <<< "$input"
>     echo
> done
'13579' : 7
'Hello, world!' : 7
'00 0 00' : 0
'!@#$%^&*();' : *
' ' : *
'3.141592' : 7
'3.1415926535897932384' : 7
manatwork
sumber
1

JavaScript (ES6), 162 159 157 byte

f=_=>{for(_=_.replace(/\W+/g,''),g=$=>''+[...$.toUpperCase()].reduce((p,a)=>isNaN(a)?p+(a.charCodeAt()-64)%9:+a+p,0);1<(l=_.length);_=g(_));return!l?'*':g(_)}

Masih mencoba mencari cara untuk menggunakan pengembalian implisit dalam fungsi luar.

Tidak disatukan + tidak ditambang

f = str => {
  str = str.replace(/\W+/g, '');
  recursiveFunc = $ => String([...$.toUpperCase()].reduce(
    (prev, val) => isNaN(val) ? prev + (val.charCodeAt() - 64) % 9 : Number(val) + prev,
    0
  ));
  while (1 < (len = str.length)) {
    str = recursiveFunc(str);
  }
  return len === 0 ? '*' : recursiveFunc(str)
}
  1. Hapus semua karakter non-alfanumerik
  2. Memanggil fungsi secara rekursif untuk mengurangi karakter ke nilai masing-masing sementara string lebih panjang dari 1 karakter.
    1. Mengubah string menjadi huruf besar agar mudah bekerja dengan kode ASCII
    2. Konversikan ke array menggunakan operator spread dan jalankan akumulator
    3. Gunakan global isNaN fungsi (yang memberikan inputnya) untuk memeriksa apakah itu bukan angka
      • Jika tidak, konversikan ke kode ASCII dan mod 9 untuk mendapatkan nilainya masing-masing
      • Jika itu angka, masukkan
  3. Jika panjangnya 0, tidak ada karakter alfanumerik yang muncul (kembalikan tanda bintang), jika tidak kembalikan output fungsi rekursif.
rink.attendant.6
sumber
Aturan istirahat ini 00 0 00, *bukan output 0!
F. Hauri
@ F. Hauri Diperbaiki.
rink.attendant.6
Anda dapat menghindari pengembalian eksplisit dengan menggunakan operator comman: _=>{expr;return expr}=>_=>(expr,expr)
Pavlo
@ Poplo Bagaimana saya menerapkannya dalam kasus saya?
rink.attendant.6
Tidak bekerja untuk saya, melempar SyntaxError: jsbin.com/havotusoqa/1/edit?js,console
Pavlo
1

Haskell, 126 byte

l x=[n|(c,n)<-zip(['0'..'9']++['a'..'z']++'\0':['A'..'Z'])$0:cycle[1..9],c==x]
g[]="*"
g[x]=show x
g x=f$show$sum x
f=g.(l=<<)

Penggunaan: f "Hello, world!"-> "7".

ladalah tabel pencarian karakter untuk daftar bilangan bulat (daftar tunggal, jika karakter ditemukan, daftar kosong jika tidak). flihat setiap karakter argumennya dan ratakan daftar daftar yang dikembalikan ke dalam daftar sederhana bilangan bulat dan panggilan guntuk memeriksa kondisi akhir (daftar kosong (-> *) atau bilangan bulat tunggal) atau untuk memanggil fdengan jumlah daftar untuk putaran lain.

nimi
sumber
1

MATL , 64 byte

jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']

Ini menggunakan versi bahasa saat ini (4.0.0) .

Saya punya perasaan bahwa itu bisa dibuat lebih pendek ...

Uji kasus

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> 13579
7

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> Hello, world!
7

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> 00 0 00
0

>> matl 
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> !@#$%^&*();
*

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> 3.141592
7

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> 3.1415926535897932384
7

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> Bob
1

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> Charlie
2

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> Anna
3

>> matl
 > jk42ht`YUt'[a-z]'XXY}3+w'[1-9]'XXY}6+h,9X\st9>]w2Y24Y2h!=~?x'*']
 > 
> Izis
9
Luis Mendo
sumber
Sayangnya, saya tidak bisa menguji sampel Anda. Silakan kirim seluruh kasus uji, termasuk tes yang baru ditambahkan (maaf).
F. Hauri
@ F. Hauri Ya, Anda perlu Matlab untuk mengujinya. Maaf tentang itu, belum ada kompiler online. Saya telah menambahkan test case
Luis Mendo
1

Serius, 50 byte

,$ù;ú1╤▀+;#pX╗@-@-;Y`'*.`╬X1WX`╜í;s9*@%u`MΣ$;lDWX

Hex Dump:

2c24973ba331d1df2b3b237058bb402d402d3b5960272a2e7f
60ce5831575860bda13b73392a402575604de4243b6c445758

Cobalah secara Online

Dijelaskan:

,$ù                                               Read input, make it a string, lowercase
    ú                                             Push lowercase alphabet
     1╤▀+                                         Prepend base 10 digits.
         ;#pX╗                                    Remove "0" from a copy and stash in reg0
   ;          @-                                  Remove alphanumerics from input copy
                @-                                Remove nonalphanumerics from input
                  ;Y                              Push 1 if string is empty, else 0
                    `'*.`╬                        If top is truthy, output * and halt
                          X                       Discard boolean
                           1                      Push 1 to enter loop
                            WX                 WX Loop while top of stack is truthy
                              `         `M        Map this function over the string
                               ╜                  Push alphanumeric string from reg0
                                í                 Push index of this char in it
                                 ;s9*             Push 9 if found, else -9
                                     @%u          Take index mod previous: this yields the
                                                  correct conversion from the numerology
                                          Σ       Sum the resulting digits.
                                           $      Convert the sum to a string.
                                            ;lD   push 1 less than its length
kuintopia
sumber
@ F. Hauri Klik "Coba Daring". masukkan kotak uji Anda di kotak input.
kuintopia
1

Pyth, 39 byte

IK@J+jkUTGrz0WtK=K`smh%xtJd9-K\0)K).?\*

Cobalah secara Online

Saya hanya melakukan ini karena saya tidak bisa tidur. Mungkin aku akan menjelaskannya besok ...

kuintopia
sumber
1

Bash murni, 199 194 byte

eval a+={a..z};r="$1";while [ "${r:1}" ];do o=;for ((i=0;i<${#r};i++));do
l=${r:i:1};case $l in [a-zA-Z])d=${a%${l,}*};((o+=$((${#d}%9+1))));;[0-9])
((o+=l));;esac;done;r="$o";done;echo "${o:-*}"

(jeda baris kedua hanya untuk menghindari scrollbar)

Aturan pengujian:

numerology() {
    eval a+={a..z};
    r="$1";
    while [ "${r:1}" ]; do
        o=;
        for ((i=0; i<${#r}; i++))
        do
            l=${r:i:1};
            case $l in 
                [a-zA-Z])
                    d=${a%${l,}*};
                    ((o+=$((${#d}%9+1))))
                ;;
                [0-9])
                    ((o+=l))
                ;;
            esac;
        done;
        r="$o";
    done;
    echo "${o:-*}"
}

for test in '13579' 'Hello, world!' '00 0 00' '!@#$%^&*();' ' ' \
            '3.141592' '3.1415926535897932384'\
            Bob Charlie Anna Fana Gregory Denis Erik Helen Izis ;do
    echo "$(numerology "$test")" $test
done
7 13579
7 Hello, world!
0 00 0 00
* !@#$%^&*();
*
7 3.141592
7 3.1415926535897932384
1 Bob
2 Charlie
3 Anna
4 Fana
5 Gregory
6 Denis
7 Erik
8 Helen
9 Izis
F. Hauri
sumber
1

JavaScript (ES6), 78 83

Solusi rekursif. Menjadi rekursi ekor, variabel t dan r tidak harus lokal.

f=x=>(t=r=0,x.replace(/\w/g,d=>t+=1+~-parseInt(d,r=36)%9),t>9?f(''+t):r?t:'*')

Dijelaskan

f=x=>(
  t = 0, // set initial value of counter to 0 
  r = 0, // flag to verify that we found at last one alphanumeric chars
  x.replace(/\w/g, d => ( // execute the following for each alphanumeric character
    // t += 1 + ~-parseInt(d,r=36) % 9 explained below
    r = 36, // set flag, could be any nonzero value
    d = parseInt(d,36), // convert to numeric. a..z -> 10..25, case insensitive.
    d = 1 + (d-1) % 9, // this is the arithmetic conversion required (
                       // works also with 0 because the strange implementation of % in javascript for negative numbers
    t = t + d // add to global counter
  ) ), 
  t > 9 // if t > 9 then we found some alphanumeric char, but we must repeat the loop on t
    ? f(''+t) // recursive call, t is numeric and must become a string
    : r // check flag r 
      ? t // if alphanumeric found, return t 
      : '*' // else return '*'
)

Cuplikan tes

f=x=>(t=r=0,x.replace(/\w/g,d=>t+=1+~-parseInt(d,r=36)%9),t>9?f(''+t):r?t:'*')

console.log=x=>O.textContent+=x+'\n';

;[['13579',7],['Hello, world!',7],['00 0 00',0],['!@#$%^&*();','*'],
['3.141592',7],['3.1415926535897932384',7],
['Bob', 1],['Charlie', 2],['Anna', 3],['Fana', 4],['Gregory', 5],
['Denis', 6],['Erik', 7],['Helen', 8],['Izis', 9]]
.forEach(t=>{
  i=t[0]+''
  k=t[1]
  r=f(i)
  console.log(i+' -> ' + r + (k==r? ' OK':' Fail - expected '+k))
  })
<pre id=O></pre>

edc65
sumber
0

Python, 154 byte

def A(S):
 D=lambda x:int(x)if x.isdigit()else (ord(x.lower())-6)%9
 while len(S)>1:S=str(sum([D(c)for c in S if c.isalnum()]))
 print S if int(S)else"*"
Kieran Hunt
sumber
Tes gagal ini dengan 00 0 00!
F. Hauri
0

Mathematica, 133 byte

f[s_]:= ToCharacterCode@ToUpperCase@s-64/.{a_/;17>-a>6:>a+16,b_/;b<1||b>26:>""}//If[Or@@NumberQ/@#,Tr@#/.""->0//.a_:>Tr@IntegerDigits@a,"*"]&

Sedikit berbeda dari LegionMammal978 di atas. Fungsi saya mengubah semuanya menjadi kode karakter, lalu memfilter hal-hal non-alfanumerik (menggantinya dengan string kosong). Jika tidak ada alfanumerik, maka akan mengembalikan *, jika tidak maka akan mengambil root digital. Ini bisa secara signifikan (~ 15B) lebih pendek jika saya tidak harus berurusan dengan case all-nol-string. C'est la vie.

Matematika Mathematica, untuk yang belum tahu: foo//.a_:>Tr@IntegerDigits@aadalah penggantian berulang: mengganti angka adi foo dengan jumlah digit mereka, lalu menggantikan lagi sampai menyentuh titik tetap, yaitu aberhenti mengubah di bawah penggantian.

Tes:

f /@ {"13579", "Hello,world!", "00 0 00", "!@#$%^&*()", "3.141592","3.1415926535897932384"}
     => {7, 7, 0, "*", 7, 7}
f /@ {"Bob", "Charlie", "Anna", "Fana", "Gregory", "Denis", "Erik",  "Helen", "Izis"}
     => {1, 2, 3, 4, 5, 6, 7, 8, 9}
hYPotenuser
sumber
Sayangnya, saya tidak bisa menguji sampel Anda. Silakan memposting kasus uji
F. Hauri
Dalam perjalanan. Saat menyusun tes, saya juga menemukan beberapa kesalahan ketik untuk diperbaiki. Terima kasih;)
hYPotenuser