탈리 표시 (다양한 기준)


16

Tallying은 기본 5에서 작동하는 간단한 카운팅 시스템입니다. 전 세계에서 사용되는 다양한 키잉 시스템이 있지만 대부분의 영어권 국가에서 사용되는 시스템은 아마도 세로선을 표시하여 가장 간단한 카운팅 단위입니다. 각 5 번째 마크는 4 개의 이전 컬렉션을 가로 질러 수평선을 표시합니다. 이렇게하면 탈리 마크가 5 개 그룹으로 묶어집니다 (빠른 계산이 더 쉬워집니다).

주어진 값까지 탈리 마크를 표시하는 프로그램을 작성하려고합니다. 그러나 5 번만 계산하는 것은 지루합니다! 따라서 프로그램은 다른 기준으로 키를 표시 할 수 있어야합니다.

입력

입력은 쉼표로 구분 된 하나 이상의 음이 아닌 정수 값입니다 (예 : 9또는 8,4). 첫 번째 숫자는 탈리에 의해 표시되어야하는 값입니다. 두 번째 값은 탈리의 기준입니다. 두 번째 값이 제공되지 않으면 밑 5를 사용하십시오 .

산출

출력은 ASCII 아트 탈리 마크로 표시된 입력 값이됩니다. 다음은 프로그램을 테스트 할 수있는 몇 가지 예입니다. 출력이 정확하게 일치해야합니다!

입력 : 12또는12,5

 | | | |   | | | |   | |
-+-+-+-+- -+-+-+-+-  | |
 | | | |   | | | |   | |

입력: 7,3

 | |   | |   |
-+-+- -+-+-  |
 | |   | |   |

입력: 4,2

 |   |
-+- -+-
 |   |

입력 : 6,1또는 6,10(앞 공백에주의)

 | | | | | |
 | | | | | |
 | | | | | |

또한베이스 1은 일관성이 없어야합니다. 세로선 만 사용해야합니다.

입력 된 값 중 하나가 0이면 출력 이 없어야합니다 (및 프로그램이 정상적으로 종료되어야 함).

규칙

  • 이것은 이므로 가장 짧은 올바른 구현 (바이트)이 이깁니다.
  • 입 / 출력은 적절한 매체 (예 : stdin / stdout, file ...)에있을 수 있습니다.
  • 입력이 여러 명령 행 인수의 형태이거나 대상 언어에 더 적합한 경우 공백 등으로 구분 될 수 있습니다.
  • 출력에서 후행 줄 바꿈이 허용됩니다. 후행 공백은 없습니다. 이 규칙은 출력이있을 때만 (즉, 입력 된 값이 0 일 때) 적용되지 않습니다.
  • 베이스가 입력되지 않은 경우 코드는 기본적으로베이스 5로 설정되어야합니다.

3
출력 결과가 6,1더 좋아 보이지 -+- -+- -+- -+- -+- -+-않습니까?
피터 테일러

3
"입력은 쉼표로 구분 된 하나 또는 두 개의 양의 정수 값입니다 (예 : 9 또는 8,4)." 우리는 주어진 것으로 그것을 받아 들일 수 있어야하며, 하나 또는 두 개의 숫자를 처리하는 것 이상으로 "프로그램이 강력해야합니다-입력을 확인해야합니다 ..."에 대해 걱정할 필요가 없습니다.
AndoDaan

1
@PeterTaylor -+-는 두 줄을 나타냅니다. 세로선과 가로선 이 있기 때문입니다. 밑면 1에는 세로선 만 있습니다. @AndoDaan이 수정되었습니다.
Sean Latham

좋아, --- --- --- --- --- ---그럼. 다른베이스와 일관성을 유지하려면 b-1수직선을 통해 수평 타격을 가해 야합니다. 일관성이없는 경우 명시 적으로 명시해야합니다.
피터 테일러

내가 해냈어 미안, 나는 그것이 암시 적이라고 생각했다.
Sean Latham

답변:


4

CJam 103 85 72

http://cjam.aditsu.net/ 에서 시도 하십시오 .

기발한

q","/(i:A\_,{~i}{;5}?:B_@*{(_{" |"*S"l"++AB/*AB%}{;MA}?\:J" |l""-+ "er\" |"*N+_J\+@2$+@J\+++"l"Ser}{;}?

공백이 있어야하는 공백에 대해 공백, 선 및 l을 가진 하나의 탈리 세트를 정의하여 작동합니다. 그런 다음 er (음역) 기능을 활용하여 두 번째 줄을 만듭니다. 가장 비효율적 인 부분은 1과 0의 특별한 경우를 처리하는 것입니다. 개선하면 편집합니다. 팁 : 두 번째 입력이 1이거나 무한대 또는 첫 번째 입력 +1과 같으므로 1과 같을 때 다시 정의하면 많은 작업이 절약됩니다.

쉼표로 구분하여 지금까지 가장 향상

l",":G/(i:A\_5a?~i:B_@*{(_" |":K*\{SG++AB/*AB%}{A}?\_KG+"-+ "er[\GSer_@@M]\K*N+*}{;}?

공간이 제한된 입력으로 지금까지 가장 개선되었습니다.

당연히 CJam은 공간이 제한된 입력을 위해 설계되었습니다. 입력을 20,3 대신 20 3에 배치하면 큰 이점이 있습니다.

ri:Aq_5s?S-i(_)A)?:B*{B(" |":K*STs++ABmd@@*_K"-+"er[\_@@M]\K*N+*TsSer}M?

5

파이썬 2 - 111 108 119 144 140 136 135 134 - 그것을 시도

좋아, 시도해 보자.

i=input()
n,b=[(i,5),i][i>[]]
o=b-1
a=[n,n%b][b>1]*' |'
m=(b>1)*n/b
s=(' |'*o+'  ')*m+a
print(s+'\n'+('-+'*o+'- ')*m+a+'\n'+s)*(b*n>0)

편집 : 나는 if n==0또는 출력이 없어야한다고 간과했습니다 b==0. 이 비용은 11 자입니다. :(

편집 : 좋아, 의견에 언급 된 두 번째 문제를 해결 한 후 내 솔루션은 기본적으로 BeetDemGuise의 문제로 수렴되었습니다.


이것은 입력 중 하나 (또는 ​​둘 다)가 0 일 때 도전을 원하지 않는 개행 문자를 인쇄합니다. 또한 프로그램에 하나의 숫자 만 입력하면 어떻게됩니까?
BeetDemGuise

1
두 번째 값을 생략하면 실패합니다 ( b이 경우 5 여야 함). 질문에서 더 명확하게 설명하겠습니다. 편집 : 오, 걱정하지 마십시오.이 의견을 말한 것처럼 수정했습니다!
Sean Latham

이것은 어느 파이썬입니까?
Beta Decay

파이썬 2.7.8입니다. -아, 맨 끝에 작은 실수가 있었다 ...
Falko

1
파이썬 2.x 인 경우 ? n/b대신에 문자를 하나 더 저장할 수 없습니다 n//b.
Emil

5

세게 때리다, 239228199 189 188

여기 내 시도가 있습니다. 골프를 많이 할 수 있습니다.

참고 : 두 번째 줄은 2에서 5를 빼지 않고 비어 있으면 기본값을 설정합니다 $2!

n=$1
b=${2-5}
((n<1&b<1))&&exit
while ((n>b&b>1));do
n=$[n-b]
x+=\
y+=-
for i in `seq $[b-1]`;{
x+='| '
y+=+-
}
x+=\
y+=\
done
for j in `seq $n`;{
x+=' |'
y+=' |'
}
echo -e "$x\n$y\n$x"

{1..$n}대신 작동 합니까 `seq $n`?
FUZxxl

@FUZxxl 불행히도 h=8;echo {1..$h}출력 하지 않습니다{1..8}

그 좋지 않다.
FUZxxl

3

파이썬 - 171 (143)

i=input();t,b=i if[0]<i else(i,5);b=[b,t+1][b==1];l,d,m,o=' |',t/b,t%b,b-1;r=(l*o+'  ')*d+l*m
if t*b>0:print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

이 프로그램은 매우 간단합니다.

  • 입력을 받고에 포장을 풀어보십시오 t,b. 실패하면 올바른 값을 지정하십시오.
  • 밑이 1이면 값을 모든 세로선을 쉽게 처리 할 수있는 값으로 변경하십시오 ( t+1).
  • 일부 변수를 설정하고 Tallies의 하단 및 상단 섹션을 만듭니다.
  • 두 경우 탈리을 인쇄 t하고 b비 제로입니다.

편집 1 : 사용 input하는 대신 기능을raw_input 약간의 재생 후 .

편집 2 : 제로가 아닌 확인으로 작은 버그를 지적한 Falko에게 감사드립니다. 이제 우리 코드는 기본적으로 동일하며 변수 이름과 작은 논리가 적습니다.

편집 3 : 파이썬이 시퀀스와 다른 유형을 비교하는 방법 덕분에 ia list와 비교 하여 더 짧은 버전의 try...except블록 을 얻을 수 있습니다 .

ungolfed 버전은 다음과 같습니다.

i=input()

# If True, `i` must be a list
if [0]<i:
    t,b=i
# Otherwise, we know its a number (since `list` comes after `int` lexicographically.)
else:
    b=5
    t=i

b = b if b==1 else t+1
l=' |'
d=t/b
m=t%b
o=b-1

r=(l*o+'  ')*d+l*m
if t and b:
    print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

내 생각 t&b이다 False10,5 위해. 그렇지 않으면 우리의 솔루션이 수렴하고 있습니다! ;)
Falko

@Falko 당신은 두 카운트에 맞습니다! 당신은 그들이 좋은 생각에 대해 무엇을 말하는지 알고 있습니다.
BeetDemGuise

i스칼라인지리스트인지 테스트 할 수있는 짧은 방법을 찾을 수 있다면 정말 좋을 것 입니다. 그런 다음 try ... except몬스터를 떨어 뜨릴 수 있습니다.
Falko

@ Falko 1 바이트 더 나은 검사를 찾았습니다. A list는 항상 정수보다 큽니다. 또한 lists는 사전 순으로 비교됩니다. 따라서 우리가 [0]<i이것을 비교 하면 항상 Falseif i가 숫자이고 Trueif i가 목록 (첫 번째 요소가 0이 아닌 경우 )을 반환 합니다 .
BeetDemGuise

1
큰! 나는 당신의 접근법을 더 단축했습니다. 좋은 팀워크! :)
Falko

3

자바, 343

class C{public static void main(String[]a){long n=new Long(a[0])+1,b=a.length>1?new Long(a[1]):5;if(b>0){if(b<2)b=(int)2e9;int i;for(i=1;i<n;i++)p(i%b>0?" |":"  ");p("\n");for(i=1;i<n-n%b;i++)p(i%b>0?"-+":"- ");if(n>b)p("- ");for(i=1;i<n%b;i++)p(" |");p("\n");for(i=1;i<n;i++)p(i%b>0?" |":"  ");}}static void p(String s){System.out.print(s);}}

덜 골프 :

class C {
  public static void main(String[] a) {
    long n=new Long(a[0])+1, b=a.length>1 ? new Long(a[1]) : 5;
    if(b>0) {
      if(b<2) b=(int)2e9; // if the base is 1, pretend the base is 2 billion
      int i;
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
      p("\n");
      for(i=1;i<n-n%b;i++) p(i%b>0 ? "-+" : "- ");
      if(n>b) p("- ");
      for(i=1;i<n%b;i++) p(" |");
      p("\n");
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
    }
  }
  static void p(String s) {
    System.out.print(s);
  }
}

별도로 선언 할 필요 ilong없도록 비용을 절약 할 수 있습니다 . i++%b>0루프를 별도로 늘리지 않고 i++<n%b세 번째 루프에서 수행 하여 몇 가지 더 하십시오 . 를 사용하여 다른 하나 b=b<2?(int)2e9:b.
Geobits

3

펄- 167 165 156

my($n,$b)=($ARGV[0]=~/(\d+)(?:,(\d+))?/,5);print$b>1?map{join(" ",($_ x($b-1))x int($1/$b)," | "x($1%$b))."\n"}(" | ","-+-"," | "):join" ",("---")x$1if$1*$b

언 골프

my($n,$b) = ($ARGV[0] =~ /(\d+)(?:,(\d+))?/, 5);
print($b>1 ?
    map{ 
        join(" ",($_ x ($b-1)) x int($1/$b)," | " x ($1%$b))."\n"
    } (" | ","-+-"," | ") :
    join " ", ("---") x $1
) if $1 * $b

기본 1에 대한 수직선 대신 수평선을 표시합니다. (
chinese perl goth

@chineseperlgoth 예, 그것은 요구 사항 중 하나입니다. Q에 대한 의견을 읽으십시오
Fozi

3

C-193

정말 죄송합니다 1의 특별한 경우를 다루는 것은 약간의 나쁜 해킹이므로 더 나은 접근 방식으로 더 골프를 칠 수 있다고 생각합니다. 또한이 코드에는 출력 시작 부분에 줄 바꿈이 포함되어 있으므로이 코드가 허용되지 않으면 알려주십시오.

물론, 아주 못생긴 표정은 항상 도움을줍니다 :)

문자 수에는 필요한 공백과 줄 바꿈 만 포함됩니다.

#define P printf(
#define L P" |")
#define A P"\n");for(i=0;i<a;)b==1?i++,L:i++&&i%b==0?P
i;
main(a,b)
{
    scanf("%d,%d",&a,&b)<2?b=5:!b?a=0:a;
    if(a){
    A"  "):L;
    A"- "):a%b&&i>a/b*b?L:P"-+");
    A"  "):L;}
}

값 중 하나가 0 일 때 코드에서 줄 바꿈을 인쇄하는 것 같습니다. 이것은 명시 적으로 허용되지 않습니다. 솔루션이 적합하지 않습니다.
FUZxxl

@FUZxxl 당신 말이 맞아 요. 이 나쁜 빠른 수정은 지금해야 할 것입니다. 더 좋은 길을 곧 찾을 수 있기를 바랍니다.
Allbeert

나는 꽤 당신은 대체하여 몇 개의 문자를 저장할 수 있습니다 확신 printf으로 puts, 그리고 대체 return삼항 연산자.
millinon

문제 @millinon로 puts그 때마다 :( 새 줄을 추가합니다. 그리고 삼항 연산자를 위해, 추가 할 수 없습니다 것입니다 return들 또는 for그들 안에이야! 나에게 아이디어를 줄 않았다 귀하의 의견은 몇 문자를 매우 저장 쉽게 제거하여 return생각을 주셔서 감사합니다.!
Allbeert

2

C # 271 바이트

가장 짧지는 않지만 입력으로 0을 수락해야하기 때문에 입력 판독 값을 골프로 칠 수 없었습니다.

using C=System.Console;class P{static void Main(){var L=C.ReadLine().Split(',');int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")f+=f<2?t:0;}}

형식화 된 코드 :

using C=System.Console;

class P
{
    static void Main()
    {
        var L=C.ReadLine().Split(',');
        int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;

        for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))
            for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")
                f+=f<2?t:0;
    }
}

1

루아 - 219 203 바이트

나는 "|"의 b 개의 복사본의 d 복사본을 만들고 "|"의 r 개의 복사본을 추가했습니다. 끝에. 어쩌면 나는 한 번에 하나씩 "|"를 문자열에 'tally up'시켜야했을 것 같은 느낌이 든다.

l=' |'s=string.rep _,_,a,b=io.read():find'(%d+)%D*(%d*)'b=tonumber(b)or 5 d=(a-a%b)/b f=b>1 and s(s(l,b-1)..'  ',d)g=b>1 and s(s('-+',b-1)..'- ',d)r=b>1 and a%b or a e=s(l,r)..'\n'print(f..e..g..e..f..e)

언 골프 :

l=' |'          --the base string
s=string.rep    --string.rep will be used a lot, so best shorten it

_,_,a,b=io.read():find'(%d+)%D*(%d*)' --reads a,b I'm probably way of the mark with this one

b=tonumber(b)or 5

d=(a-a%b)/b -- shorter than math.floor(a/b), d equal the vertical mark

f=b>1 and s(s(l,b-1)..'  ',d) or '' --creates d multiples of b multiples of "|" more or less
g=b>1 and s(s('-+',b-1)..'- ',d)or''--same as above but with the middle "-+-"

r=b>1 and a%b or a --idk maybe i should set r before d(a- a%b )/b

e=s(l,r)..'\n'  -- makes the remainder string, notice that if b==1  then e will output all the "|" 

print(f..e..g..e..f..e) -- here's where the real magic happens!

견본:

c:\Programming\AnarchyGolfMine>lua test.lua
13,5
 | | | |   | | | |   | | |
-+-+-+-+- -+-+-+-+-  | | |
 | | | |   | | | |   | | |


c:\Programming\AnarchyGolfMine>lua test.lua
6,2
 |   |   |
-+- -+- -+-
 |   |   |


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |

1
훨씬 더 읽기 쉽고 골치 아픈 버전을 게시 할 수 있습니까? 루아에서의 골프는 재미있어 보인다!

@Alessandro가 끝났습니다. 그리고 고마워, 내가 놓친 몇 가지를 발견했습니다.
AndoDaan

1

자바 스크립트 (193)

지나치게 복잡 할 수 있습니다.

s=prompt().split(",");a=+s[0];b=s[1];b=b?+b:5;o=b>1;v=" | ";q=w="";for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")for(i=o;c&&i<b;i++)c--,q+=v,w+=g&&o?"-+-":v;if(a&&b)console.log(q+'\n'+w+'\n'+q)

댓글 버전

s=prompt().split(",");
a=+s[0];
b=s[1];
b=b?+b:5;   // convert b to int and default to 5
o=b>1;      // special handling for b0 and b1
v=" | ";
q=w="";
// calculate number of lines and number of groups
for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")
    for(i=o;c&&i<b;i++)
        c--,  // decrease line count
        q+=v,
        w+=g&&o?"-+-":v; // use " | " for last group and "-+-" for others
if(a&&b) // handle b0
    console.log(q+'\n'+w+'\n'+q)

1

파이썬 - 127 (123) (122)

약간 짧은 파이썬 버전으로 몰래 들어가십시오.

편집 : 고정 0은 아무것도 인쇄하지 않고 다시 트리거하여 같은 길이로 끝났습니다.

k=input()
k=i,j=((k,5),k)[k>[]]
for m in[' |','-+',' |']*all(k):
 print(m*(j-1)+m[0]+' ')*(i/j*(j>1))+' |'*(i%(j+(j<2)*i))

0

C (207 자)

바로 앞의 줄 바꿈 exit은 가독성을위한 것입니다.

#define P printf(
#define t(v)for(a=c;b<=a;a-=b)a-c&&P" "),P v+1),q(b,v);q(a," |");P"\n");
q(n,c){while(n--)P c);}a;b;c;main(){scanf("%d,%d",&c,&b)<2?b=5:0;b&&c||
exit();b==1?b=32767:0;t("| ")t("+-")t("| ")}

scanfAllbeert에서 도난당한 shamelessy. 이 솔루션은 존재하지 않는 프로토 타입을 적용하려고 시도하므로 gcc로 컴파일되지 않습니다 exit. 다음과 같이 작동하는 C 컴파일러로 컴파일하십시오.tcc . 또한이 기능은 64 비트 플랫폼에서 작동하거나 작동하지 않을 수 있습니다. 주의해서 사용하십시오.

다음은이를 기반으로하는 원래 ungolfed 구현입니다.

#include <stdio.h>
#include <stdlib.h>

static void
tally_line(int base, int count, const char *str)
{
     int follower = 0, i;

     /* full tallies first */
     for (; count >= base; count -= base) {
          if (follower++)
               putchar(' ');

          /* only print second character */
          printf(str + 1);

          for (i = 0; i < base; i++)
               printf(str);
     }

     /* partial tally */
     for (i = 0; i < count; i++)
          printf(" |");

     /* newline */
     puts("");
}

extern int
main(int argc, char **argv)
{
     int base, count;

     /* do away with program name */
     count = atoi(*++argv);

     base = argc - 3 ? 5 : atoi(*++argv);

     /* remove 0 later */
     base | count || exit(0);

     /* a crossed-out tally never appears for large numbers */
     if (base == 1)
          base = 32767;

     tally_line(base, count, "| ");
     tally_line(base, count, "+-");
     tally_line(base, count, "| ");

     return (EXIT_SUCCESS);
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.