수비학 계산기


19

이 과제의 목표는 문자와 숫자를 포함하는 문자열에서 한 종류의 수비학 숫자 를 계산하는 입니다.

  • 입력은 편리한 방법 (표준 입력, 인수, 분리 된 파일)을 통해 이루어질 수 있습니다.
  • 입력은 어떤 인쇄 가능한 ASCII 문자를 포함하지만, 알파벳과 숫자 만 (수 A-Z, a-z0-9)은 고려되어야한다.
  • 출력은 숫자 사이에 있어야 1하고 9또는 별 *의 경우 어떤 문자와 ... 찾을 수 없습니다 자리 (또는 0입력이 어떤 수를 포함하는 경우 0 다른 아무것도 그러나 이것은 중요하지 않습니다).
  • 문자 값은 다음과 같이 매핑됩니다.

    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
    
  • 수비학 숫자가 하나 개의 숫자가 될 때까지 캐릭터의 각각의 값을 가산함으로써 계산되고, 다음 반복한다. 샘플에 대한 13579, Hello, world!, 00 0 00, !@#$%^&*();, 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
    

    (이것은 훌륭합니다.이 샘플의 대부분은 제공합니다 7!하지만 샘플 일뿐입니다.)

    몇 가지 더 테스트 :

    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
    

이것은 이므로 바이트 단위의 최단 답변이 이깁니다.

언어 별 최단


다른 것에 추가하면 0이 사라질 것입니다
F. Hauri

0은 관련이 없습니다! 관련 출력 사이 19!
F. Hauri

영숫자가없는 예제를 추가 할 수 있습니까?
ETHproductions

1
나는 같은 것을 의미한다 !@#$%^&*(). 반환해야 할 것 *.
ETHproductions

Money 영역에 대한 기술 분석 토론에서 이것을 인용하는 것은 매우 어려운 일입니다 ...
;-p

답변:


6

Matlab, 121 바이트

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은 문자열을 위해 만들어지지 않았습니다 = (


3
이봐, 최소한 Mma만큼 장황하지는 않아 : P
LegionMammal978

내 +1, 더 잘할 수 없었습니다. btw, disp진술서를 작성해야합니까?
brainkz

@brainkz 어쩌면, 그러나 나는 보통 그것이 안전한면에
flawr

3

매쓰, 174 (168) 163 바이트

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]]&

첫 번째 단계를 수행 한 다음 디지털 루트를 계산합니다.


3

루비, 97 74 자

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

샘플 실행 :

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

3

펄, 91 89 76 74 바이트

에 73 + 1 -p스위치의 경우

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

테스트

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

저장하는 데 도움을 주신 @manatwork에게 감사합니다. 2 14 16 15 17 문자!!

... 나는 생각했다 : N % 32 + Y대체 할 수 있습니다( N & 31 ) + Y !


1
일치하는 전체 하위 문자열을 캡처하면 $1과 같습니다 $&. 따라서 캡처를 제거하고 변수 이름을 변경하십시오.
manatwork

1
while차단 될 수 있습니다 $t="*";s/\d/$t+=$&/eg;$_=$t.
manatwork

1
죄송하지만 -p카운트에 스위치를 포함해야하므로 실제로 1 자 더 깁니다 .
manatwork

1
다시 죄송합니다 (이번에는 더 큰 죄송합니다). 단어가 아닌 단일 문자 입력에서 실패합니다 (예 :“!”의 결과는”!”). ( 여기 문자열로 입력하면 항상 줄 바꿈 문자가 전달되므로 테스트 사례에서는 단일 문자 입력을 절대로 통과하지 않기 때문에 작동하는 것 같습니다 . echo -n "$test" | perl -pe '…'의미를 확인하는 데 사용 하십시오.) while조건을 로 변경하여 해결할 수 있습니다 !/^[\d*]$/. 점수 손실을 줄이기 위해 전체 점수 while를 다음과 같이 바꿀 수 있습니다 $t="*",s/\d/$t+=$&/eg,$_=$t until/^[\d*]$/.
manatwork

1
한 가지 더 개선 할 수 있습니다. 로 &보다 낮은 우선 순위를 가지고 +있지만, %높은, 변화가 &31%32하고 해당 표현식 주위에 괄호를 제거 할 수 있습니다.
manatwork

3

ES6, 98 바이트

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:'*'

언 골프 드 :

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 : "*";
}

짧은 문자열에서만 작동하는 94 바이트 버전 :

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

사용 match, mapjoin사용하는 것보다 짧은 것으로 밝혀졌다 replace회 :

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

여기에서 테스트하십시오 : https://jsbin.com/zizosayisi/edit?js,console


입력에 대해서는 작동하지 않습니다00 0 00
rink.attendant.6

@ rink.attendant.6 아아, 내가 사용한 REPL은 단지 차이점을 알 수 없었기 때문에 단지 인쇄물 ["0"]을 사용했습니다 0.
Neil

@ rink.attendant.6 버전보다 훨씬 좋습니다! 영리한 골프 핵이 사용되었습니다. 당신이 설명 할 수있는 > '@', & 31그리고 || 9?
Pavlo

1
@Pavlo > '@'는 문자와 숫자를 구별합니다. & 31문자 코드를 1..26 값으로 편리하게 직접 매핑하기 때문에 대문자와 소문자 문자 코드의 차이를 무시하는 유용한 방법입니다. || 9% 99의 배수에 대해 0을 반환하지만 숫자를 반복적으로 추가하면 0이 아닌 배수에 대해 9를 반환 하기 때문에 사용됩니다 . 골프 코드에서는 (t + 8) % 9 + 1대신 동일한 것을 사용합니다.
Neil

이 언어의 이름은 일반적으로 "JavaScript (ES6)"입니다.
edc65

2

관장, 161 자

*=@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}}}

재귀 도메인 호출이 작동하는지 여부 만 기록합니다.

샘플 실행 :

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

1

자바 스크립트 (ES6), 162 (159) 157 바이트

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(_)}

여전히 외부 함수에서 암시 적 반환을 사용하는 방법을 찾고 있습니다.

언 골프 + 축소

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. 영숫자가 아닌 모든 문자를 제거합니다
  2. 문자열이 1자를 초과하는 동안 문자를 각각의 값으로 줄이기 위해 함수를 재귀 적으로 호출합니다.
    1. ASCII 코드로 쉽게 작업 할 수 있도록 문자열을 대문자로 변환
    2. 스프레드 연산자를 사용하여 배열로 변환하고 누산기를 실행
    3. 전역 isNaN함수 (입력을 캐스트)를 사용하여 숫자가 아닌지 확인하십시오.
      • 그렇지 않은 경우 ASCII 코드와 모드 9로 변환하여 해당 값을 가져옵니다.
      • 숫자이면 캐스트
  3. 길이가 0이면 영숫자 문자가 없었으며 (별표를 반환) 그렇지 않으면 재귀 함수의 출력을 반환합니다.

이 중단 규칙 00 0 00, *대신 출력 0!
F. Hauri

@ F.Hauri 고정.
rink.attendant.6

comman 연산자를 사용하여 명시적인 리턴을 피할 수 있습니다. _=>{expr;return expr}=>_=>(expr,expr)
Pavlo

@Pavlo 제 경우에는 어떻게 적용합니까?
rink.attendant.6

나를 위해 작동하지 않습니다, SyntaxError가 발생합니다 : jsbin.com/havotusoqa/1/edit?js,console
Pavlo

1

하스켈, 126 바이트

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=<<)

사용법 : f "Hello, world!"-> "7".

l문자가 정수 목록을 표시하는 룩업 테이블입니다 (단일 목록, 문자가 있으면 빈 목록, 그렇지 않으면 빈 목록). f인수의 모든 문자를 조회하고 리턴 된 목록 목록을 간단한 정수 목록으로 평면화하고 g종료 조건 (빈 목록 (-> *) 또는 단일 정수)을 확인하거나 f다른 라운드의 목록 합계 를 호출하도록 호출 합니다.


1

MATL , 64 바이트

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

이것은 사용 최신 버전 (4.0.0) 의 언어를.

더 짧아 질 수 있다고 생각합니다.

테스트 사례

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

불행히도, 나는 당신의 샘플을 테스트 할 수 없습니다. 최근에 추가 된 테스트를 포함하여 전체 테스트 사례를 게시하십시오 (죄송합니다).
F. Hauri

@ F.Hauri 예, 테스트하려면 Matlab이 필요합니다. 죄송합니다. 아직 온라인 컴파일러가 없습니다. 테스트 사례를 추가했습니다
Luis Mendo

1

진심으로, 50 바이트

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

육각 덤프 :

2c24973ba331d1df2b3b237058bb402d402d3b5960272a2e7f
60ce5831575860bda13b73392a402575604de4243b6c445758

온라인으로 사용해보십시오

설명 :

,$ù                                               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

@ F.Hauri "온라인으로 시도"를 클릭하십시오. 입력 상자에 테스트 사례를 입력하십시오.
quintopia


1

순수한 bash, 199 194 바이트

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:-*}"

(두 번째 줄 바꿈은 스크롤 막대를 피하기위한 것입니다)

테스트 규칙 :

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

1

자바 스크립트 (ES6), 78 83

재귀 솔루션. 꼬리 재귀이므로 변수 t와 r은 지역적이 아니어야합니다.

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

설명

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 '*'
)

테스트 스 니펫

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>


0

파이썬, 154 바이트

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"*"

이로 실패 테스트 00 0 00!
F. Hauri

0

수학, 133 바이트

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,"*"]&

위의 LegionMammal978과 약간 다릅니다. 내 함수는 모든 것을 문자 코드로 변환 한 다음 영숫자가 아닌 것을 필터링합니다 (빈 문자열로 대체). 영숫자가 없으면 *를 반환하고 그렇지 않으면 디지털 루트를 사용합니다. 0이 아닌 문자열을 처리 할 필요가 없다면 이것은 (~ 15B) 상당히 짧을 수 있습니다. C'est la vie.

Mathematica magic은 초기화되지 않은 경우 : foo//.a_:>Tr@IntegerDigits@a반복되는 대체입니다. afoo의 숫자를 숫자의 합계로 바꾼 다음 고정 소수점에 도달 할 때까지 다시 바꿉니다 (예 a: 교체 중에 변경이 중지됨).

테스트 :

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}

불행히도, 나는 당신의 샘플을 테스트 할 수 없습니다. 테스트 사례를 게시하십시오
F. Hauri

가는 길에 테스트를 종합하면서 수정해야 할 오타도 발견했습니다. 감사합니다;)
hYPotenuser
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.