크리스 파인의“청각 장애인 할머니”


22

저는 RubyLearning의 멘토이며 우리 학생들에게 제공하는 연습 중 하나는 Chris Pine의 저서 " Learn to Program " 의 "Deaf Grandma"연습입니다 . 설명은 다음과 같습니다.

귀머거리 할머니 프로그램을 작성하십시오. 당신이 할머니에게 무엇을 말하든, 무엇을 입력 하든지, 그녀는 "음?! 당신이 소리 치면, 그녀는 당신을들을 수 있고 (적어도 그녀는 그렇게 생각한다) "아니, 1938 년 이래!"

당신의 프로그램을 정말로 믿을 수있게하려면, 매번 할머니가 다른 소리를 지도록하십시오. 아마도 1930 년에서 1950 년 사이의 임의의 연도 일 수 있습니다. (이 부분은 선택 사항이며, 메소드 장 끝에있는 루비의 난수 생성기 섹션을 읽으면 훨씬 더 쉬울 것입니다.) "BYE"를 외치십시오.

몇 번의 과정을 반복 한 후이 크기를 얼마나 작아서 112 자까지 줄일 수 있는지 확인하려고했습니다.

puts (s||='').upcase==s ? "NO, NOT SINCE #{1930+rand(21)}!":"HUH?! SPEAK UP, SONNY!" until(s=gets.chomp)=="BYE"

루비가 이미 여기서 잘하고 있다고 생각하기 때문에 원하는 언어로 몇 가지 문자를 얻을 수 있는지 궁금합니다.

편집 : 아래에 게시 된 Perl 솔루션은

ruby -nle 'puts($_=="BYE"?exit: $_.upcase!? "HUH?! SEPAK UP, SONNY!":"NO, NOT SINCE #{1930+rand(21)}!")'

이는 표현식의 경우 92 자, nl옵션의 경우 2 자입니다 .


골프 상황에서는 추가 사양이 필요합니다. BYE 이후에 추가 출력이 있으면 어떻게됩니까?
JB

"BYE"만이 프로그램을 정확하게 종료합니다.
Michael Kohl

답변:


13

펄, 85 91

다음으로 실행 perl -nE '<code goes there>'( n프로그램 크기로 계산) :

$==1930+rand 21;say/^BYE$/?last:uc eq$_?"
NO, NOT SINCE $=!":"HUH?! SPEAK UP, SONNY!"

그 느낌표는 매우 비쌉니다 ...

IK가 제안한 수정 사항 :

  • 문자열 일치 대신 정규 표현식을 사용하면 -l전역 옵션과 두 개의 프로그램 문자 -3이 절약 됩니다.
  • 실제 변수를 사용하여 값을 저장하고 나중에 보간에 사용합니다 (Genius! 누가 변수를 사용하려고했을까요?) : 0.
  • 해당 변수를 $=정수로 제한 : -4.

(그리고 여전히 합산되지 않으며 이유를 찾기에는 너무 졸려요. 아, 적어도 마지막 카운트는 맞습니다)


$="BYE"에 대한 정규 표현식을 남용 하고 사용하면 84 + 1로 perl -nE '$==1930+rand 21;say/^BYE$/?last:uc eq$_?"NO, NOT SINCE $=!":"HUH?! SPEAK UP, SONNY!"'
줄어 듭니다

@IlmariKaronen 통합, 감사합니다!
JB

6

파이썬 120 자

r=raw_input
s=r()
while'BYE'!=s:
 print["HUH?! SPEAK UP, SONNY!","NO, NOT SINCE %d!"%(1930+id(s)%21)][s.isupper()];s=r()

개선 할 힌트가 있습니까?


if 문 주위에 대괄호가 필요하지 않으며, 파이썬에 재귀 상한이 있다고 확신하지만 할머니가 잠들고있는 것처럼 보일 수 있습니다.
Phoshi

오! 브래킷을 제거하는 것을 잊었습니다. 감사합니다 :)
fR0DDY

첫 번째 줄을 제거하고 두 번째 줄을으로 바꾸고 s=''while 루프에서 명령문을 재정렬하고 전체 루프를 한 줄에 넣으면 일부 문자를 저장할 수 있습니다 . gist.github.com/3787809 실제로 결정된 경우 파이썬 3을 사용하여 2자를 저장하십시오 (raw_input ()-> input (), 그러나 print-> print ())
Matt

4

PowerShell에서 131 자 :

for(){$j=read-host;if($j-ceq"BYE"){break}if($j-ceq$j.ToUpper()){"No, not since 19$(10..90|random)!"}else{"Huh?! Speak up, sonny!"}}

공백 포함 :

for(){
  $j = read-host;
  if ( $j -ceq "BYE" ) { break }
  if ( $j -ceq $j.ToUpper() ) { "No, not since 19$(10..90|random)!" }
  else { "Huh?! Speak up, sonny!" }
}

Joey의 제안에서 18자를 압착했습니다.

BTW, 'Learn to Program'은 제가 처음으로 커버를 읽은 프로그래밍 책이었습니다.


여기서 살펴 봐야 할 수 있습니다 : codegolf.stackexchange.com/questions/191/...
조이에게

첫 번째 if...를 조건부 검사 에 squishing하여 이것을 120으로 줄일 수 있습니다 for(). for(;($j=read-host)-cne"BYE"){if($j-ceq$j.ToUpper()){...또한 사양에 1930-1950이 나와 있습니다.
철자

3

C #-234 문자

using System;class P{static void Main(){for(;;){var s=Console.ReadLine();if(s!=s.ToUpper()){Console.WriteLine("Huh?! Speak up, sonny!");continue;}if(s=="BYE")break;Console.WriteLine("No, not since 19{0}!",new Random().Next(30,51));}}}

더 읽기 쉬운 :

using System;
class P
{
    static void Main()
    {
        for(;;)
        {
            var s=Console.ReadLine();
            if(s!=s.ToUpper())
            {
                Console.WriteLine("Huh?! Speak up, sonny!");
                continue;
            }
            if(s=="BYE")
                break;
            Console.WriteLine("No, not since 19{0}!",new Random().Next(30,51));
        }
    }
}

아 내에서 몇 가지 간단한 것들을 그리워하고 바보 같은 실수를 저질렀습니다. Nice +1
Kyle Rozendo

3

Befunge-27x6 = 162 자

> ~:0`  #v _            vv<
         >:"a"`!#v  _:"z"`|
^                <       <
v"Huh?! Speak up, sonny!"0<
v"No, not since 1938!"0 <
>:# #, _@

편집 : "BYE"부분을 완전히 놓쳤다. 새로운 버전이 곧 나옵니다.

편집 2 : 실제로, 그것은 나의 빈약 한 Befunge 기술을 위해 너무 복잡합니다. 나중에 다시 시도 할 수도 있지만 현재로서는 구현할 간단한 방법을 생각할 수 없습니다.


3

C #-194 문자

using System;class P{static void Main(){var s=Console.ReadLine();if(s!="BYE"){Console.Write((s==s.ToUpper()?"No, not since 19"+new Random().Next(30, 51):"Huh?! Speak up, sonny")+"!");Main();}}}

공백으로 :

using System;
class P
{
    static void Main()
    {
        var s = Console.ReadLine();
        if (s != "BYE")
        {
            Console.Write((s == s.ToUpper() ? "No, not since 19" + new Random().Next(30, 51) : "Huh?! Speak up, sonny") + "!");
            Main();
        }
    }
}

Nellius와 fR0DDY에서 영감을 얻었습니다.

개선 될 수 있는지 알려주십시오.


짧지 만 FWIW, 이것이 누출된다고 생각합니다 (재귀 적으로 호출 Main()). 또한, 나는 당신이 ?:표현 에서 parens !둘 다를 얻기 를 원한다고 생각합니다 . 나는 이것과 EOL에 대한 답변을 추가했습니다 (그러나 여전히 누출됩니다).
bw

나는 당신이 parens를 추가하고 당신의 의견을 제거하는 것을 봅니다. 잘 했어. 이제 parens의 유무에 관계없이 스크린 샷을 추가하는 편집은 무례합니다. (그러나 여전히 새는) :-)
bw

@bill 예, 처음에 테스트를 망쳤습니다. 비누 수 버전은 199 자이며 waaay가 너무 깁니다 :)
Richard

하아. 나는 Main();해결책을 좋아한다 ... 제정신이 아닌 사람은이 프로그램을 오랫동안 문제로 사용할 수 없을 것이다.
bw

Phoshi가 fR0DDY에 대한 의견에서 말했듯이. 할머니가 잠들 때 프로그램이 충돌합니다.
Richard

3

D : 246 자

import std.random,std.stdio,std.string;void main(){auto r=rndGen();for(;;){auto t=strip(readln());if(t=="BYE")break;if(t.toupper()==t)writefln("No, not since %s!",{r.popFront();return r.front%20+1930;}());else writeln("Huh?! Speak up, sonny!");}}

더보기 :

import std.random, std.stdio, std.string;

void main()
{
    auto r = rndGen();

    for(;;)
    {
        auto t = strip(readln());

        if(t == "BYE")
            break;

        if(t.toupper() == t)
            writefln("No, not since %s!", {r.popFront(); return r.front % 20 + 1930;}());
        else
            writeln("Huh?! Speak up, sonny!");
    }
}

3

자바 스크립트, 142 자, 그 중 29 명이 무작위 연도를 수행합니다.

n='a'; while((/[a-z]/.test(n)?r="HUH?! SPEAK UP, SONNY!":n=="BYE"?r='':r="NO, NOT SINCE "+Math.floor(Math.random()*21+1930))!=''){n=prompt(r)}

3

Awk : 97 자

$0=="BYE"{exit}$0=toupper($0)==$0?"NO, NOT SINCE "int(rand()*21+1930)"!":"HUH?! SPEAK UP, SONNY!"

3

Windows PowerShell을, 121 (117)

작업의 특성으로 인해 독립적으로 작성되었지만 Ty Auvil의 솔루션 과 거의 동일하게 보입니다 .

for(;($j=read-host)-cne'BYE'){if($j-cmatch'[a-z]'){'Huh?! Speak up, sonny!'}else{"No, not since 19$(30..50|random)"}}

제안에 대한 SpellingD 덕분에


나는 정규식 일치를 좋아하지만 switch 문은 부피가 큽니다. 내가 Ty에게 준 제안과 함께 다음과 같이 정규 표현식을 사용하여 캐릭터 수를 117로 줄일 수 있습니다 if.for(;($j=read-host)-cne'BYE'){if($j-cmatch'[a-z]'){'Huh?! Speak up, sonny!'}else{"No, not since 19$(30..50|random)"}}
SpellingD

2

하스켈 (189)

import Random
import Char
main=getLine>>=g
g"BYE"=return""
g s|s/=map toUpper s=putStrLn"HUH?! SPEAK UP SONNY!">>main|4>2=randomRIO(30,50::Int)>>=putStrLn.("NO, NOT SINCE 19"++).show>>main

이상한 점은 Haskell 코드는 일반적으로 '심각한'프로그램을 작성할 때 비슷한 C 코드보다 훨씬 짧습니다.


소문자를 테스트 Char하는 데 사용하여 가져 오기 를 피할 수 있습니다 any(`elem`['a'..'z'])s.
hammar

2

APL (76)

 {'BYE'≢A←⍞:∇⎕←{∧/⍵∊⎕A:'No, not since ',⍕1938+?20⋄'Huh?! Speak up sonny!'}A}⍬

1

C #-345 문자

using System;class Program{static void Main(){for(;;){if(!t(Console.ReadLine()))break;}}static bool t(string s){bool b=false;if(s=="BYE")return b;int i=0;for(;i<s.Length;i++){b=(s[i]>65&&s[i]<90)?true:false;if(!b)break;}if(b) p("NO, NOT SINCE 1938!");else p("HUH?! SPEAK UP, SONNY!");return true;}static void p(string s){Console.WriteLine(s);}}

젠장 장황한 언어 ... :-)


1
당신은 그냥 클래스를 호출 할 수 있습니다 P. 그리고 이것은 대문자를 올바르게 감지하지 못합니다. 나는 소리를 질러도 여전히 내 말을들을 수 없습니다. 기본 방법을로 단축 할 수 있습니다 while(t(Console.ReadLine()));. 당신은 사용할 수 있습니다 using C=System.Console;에 대한 액세스 권한을 단축하기 위해 시작 ReadLine()WriteLine()C.ReadLine()C.WriteLine().
Joey

@Joey-팁 주셔서 감사합니다!
Kyle Rozendo

1

C #-196 자 (누수)

using System;class P{static void Main(){var s=Console.ReadLine();if(s!="BYE"){Console.Write((s==s.ToUpper()?"No, not since 19"+new Random().Next(30, 51):"Huh?! Speak up, sonny")+"!\n");Main();}}}

그것은 두 개의 parens (아래 참조)와 \ n이 추가되어 @Richard (누설) 대답이며 두 경우 모두 EOL을 얻습니다. 그렇지 않으면 " + "공간이 낭비됩니다.

형식화

using System;
class P
{
    static void Main() { 
        var s = Console.ReadLine(); 
        if (s != "BYE") { 
            Console.Write((
                s == s.ToUpper() ? 
                "No, not since 19" + new Random().Next(30, 51) : 
                "Huh?! Speak up, sonny"
                ) + "!\n");
            Main(); 
        } 
    }
}

업데이트 : 필요한 parens에 대한 내 의견을 명확히하기 위해 parens없이 얻는 것입니다 (예 : @Richard의 원래 솔루션으로).

괄호없이

그리고 괄호와 함께 :

Parens와 함께

이 중 어느 것도 내 추가를 사용하지 않습니다 \n.


여기는 195입니다. 마지막에 불필요한 줄 바꿈을 계산 했습니까?
Joey

1

배쉬 : 136128

while read s
do
[[ $s = BYE ]]&&break
[[ ${s^^} = $s ]]&&echo NO, NOT SINCE $[RANDOM%21+1930]!||echo HUH?! SPEAK UP, SONNY!
done

제한 대안 : (132) 123 자

f(){
read s
[[ $s = BYE ]]||{
[[ ${s^^} = $s ]]&&echo NO, NOT SINCE $[RANDOM%21+1930]!||echo HUH?! SPEAK UP, SONNY!
f
}
}
f

청각 장애인과 무한 대화 할 수 있지만이 이후 코드와의 대화는 호출 스택에 의해 제한됩니다. (내 테스트에서 4989 호출 후 종료됩니다.)


1

자바 - 133 개 131 130 128 127 121 문자

www0z0ks 솔루션의 골프 버전

g='';while((i=prompt(g))!='BYE'){/[a-z]/.test(i)?g='Huh?! Speak up, sonny!':g='No, not since '+Math.floor(Math.random()*21+1930)+'!'}

g='';while((i=prompt(g))!='BYE'){g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.floor(Math.random()*21+1930)+'!'}

g='';while((i=prompt(g))!='BYE'){g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.ceil(Math.random()*21+1929)+'!'}

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.ceil(Math.random()*21+1929)+'!');

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+parseInt(Math.random()*21+1930)+'!');

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+(Math.random()*21+1930|0)+'!');

편집 : 이 훌륭한 팁으로 또 다른 6자를 저장했습니다 .


삼항 연산자를 작성하고 g=/[a-z]/.test(i)?'Huh?!...':'No...'2 문자를 절약하십시오.
manatwork

포인터 덕분에 편집되었습니다.
codeporn

1
내가 찾은 캐릭터가 1 개 Math.ceil()더 많습니다 Math.floor(). 간격을 변경하지 않으려면 기준 연도를 변경하십시오 Math.ceil(Math.random()*21+1929).
manatwork

좋아요, +1! while을 for 루프로 변경하여 다른 두 문자를 저장했습니다.
codeporn

0

Clojure의 - (160 개) 154 문자

(#(if(= % "BYE")%(do(if(=(.toUpperCase %)%)(prn(str"No, not since "(+ 1930(rand-int 9))"!"))(prn"Huh?! Speak up, sonny!"))(recur(read-line))))(read-line))

좀 더 골프를 타기. 제안을 환영합니다.

REPL을 통해 실행


0

문 115

{while[1;v:read0 0;$[v~"BYE";'`;v~upper v;-1"No, not since ",/:(($)1?1930+(!)20),'"!";-1"Huh?! Speak up, sonny!"]]}

용법

q){while[1;v:read0 0;$[v~"BYE";'`;v~upper v;-1"No, not since ",/:(($)1?1930+(!)20),'"!";-1"Huh?! Speak up, sonny!"]]}`
Hi
Huh?! Speak up, sonny!
Hello
Huh?! Speak up, sonny!
HELLO!
No, not since 1938!
Goodbye Grandma
Huh?! Speak up, sonny!
BYE
'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.