그리드 교차 시퀀스


17

그래프 용지를 가져 와서 m단위가 오른쪽으로 n향하는 기울어 진 선을 그리면 n-1가로 및 m-1세로 눈금 선이 순서대로 교차 합니다. 해당 시퀀스를 출력하는 코드를 작성하십시오.

예를 들어 m=5n=3제공합니다.

m = 5, n = 3에 대한 눈금 선 교차

아마도 관련 : 유클리드 리듬 생성 , 피보나치 타일링 , FizzBuzz

입력 :m,n 상대적으로 소수 인 양의 정수 두 개

출력 : 교차점을 두 개의 고유 한 토큰으로 반환하거나 인쇄합니다. 예를 들어, 문자열이 될 수 HV의 목록 TrueFalse , 또는 0's와 1'별도의 줄에 인쇄 s의. 가변 개수의 공백이 아니라 항상 동일하다면 토큰 사이에 구분 기호가있을 수 있습니다.

테스트 사례 :

첫 번째 테스트 사례는 빈 출력이거나 출력이 없습니다.

1 1 
1 2 H
2 1 V
1 3 HH
3 2 VHV
3 5 HVHHVH
5 3 VHVVHV
10 3 VVVHVVVHVVV
4 11 HHVHHHVHHHVHH
19 17 VHVHVHVHVHVHVHVHVVHVHVHVHVHVHVHVHV
39 100 HHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHH

형식으로 (m,n,output_as_list_of_0s_and_1s):

(1, 1, [])
(1, 2, [0])
(2, 1, [1])
(1, 3, [0, 0])
(3, 2, [1, 0, 1])
(3, 5, [0, 1, 0, 0, 1, 0])
(5, 3, [1, 0, 1, 1, 0, 1])
(10, 3, [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1])
(4, 11, [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0])
(19, 17, [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1])
(39, 100, [0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0])

2
오늘 PPCG : 골프 Bresenham의 선 그리기 알고리즘
Sparr

추가 한 대체 형식에 따라 출력의 일부로 입력을 반복해야합니까? 그렇지 않으면 입력과 출력이 동일한 목록의 일부인 이유를 이해할 수 없습니다.
Reto Koradi 2016 년

@RetoKoradi 아니요, 입력 내용을 포함해서는 안됩니다. 테스트 케이스를 쉽게 처리 할 수 ​​있도록 튜플에 넣었습니다.
xnor

답을 예측할 수는 있지만 물어 보는 것은 아프지 않습니다. 공백 문자를 출력 토큰 중 하나로 사용할 수 있습니까? 결과적으로 출력에 중요한 선행 / 트레일 공간이있을 수 있습니다. 다른 공간은 없으므로 모든 공간이 중요합니다.
Reto Koradi

@RetoKoradi 아니오, 후행 공백이 보이지 않기 때문입니다.
xnor

답변:


7

루비, 92; 타조 0.7.0 , 38

f=->m,n{((1..m-1).map{|x|[x,1]}+(1..n-1).map{|x|[1.0*x*m/n,0]}).sort_by(&:first).map &:last}
:n;:m1-,{)o2W}%n1-,{)m n/*0pW}%+_H$_T%

둘 다에 대한 출력은 1과 0을 사용합니다 (예 :) 101101.


타조에 대한 설명은 다음과 같습니다.

:n;:m    store n and m as variables, keep m on the stack
1-,      from ex. 5, generate [0 1 2 3]
{...}%   map...
  )        increment, now 5 -> [1 2 3 4]
  o        push 1 (the digit 1 is special-cased as `o')
  2W       wrap the top two stack elements into an array
           we now have [[1 1] [2 1] [3 1] [4 1]]
n1-,     doing the same thing with n
{...}%   map...
  )        increment, now 3 -> [1 2]
  m n/*    multiply by slope to get the x-value for a certain y-value
  0        push 0
  pW       wrap the top two stack elements (2 is special-cased as `p')
+        concatenate the two arrays
_H$      sort-by first element (head)
_T%      map to last element (tail)

루비 코드를 가이드로 사용하여 전체 작동 방식에 대한 설명 :

f = ->m,n {
    # general outline:
    # 1. collect a list of the x-coordinates of all the crossings
    # 2. sort this list by x-coordinate
    # 3. transform each coordinate into a 1 or 0 (V or H)
    # observation: there are (m-1) vertical crossings, and (n-1) horizontal
    #   crossings. the vertical ones lie on integer x-values, and the
    #   horizontal on integer y-values
    # collect array (1)
    (
        # horizontal
        (1..m-1).map{|x| [x, 1] } +
        # vertical
        (1..n-1).map{|x| [1.0 * x * m/n, 0] }  # multiply by slope to turn
                                               # y-value into x-value
    )
    .sort_by(&:first)  # sort by x-coordinate (2)
    .map &:last        # transform into 1's and 0's (3)
}

5

파이썬, 53

True / False 목록 출력을 사용합니다. 여기서 특별한 것은 없습니다.

lambda m,n:[x%m<1for x in range(1,m*n)if x%m*(x%n)<1]

4

Pyth- 32 24 바이트

Jmm,chk@Qddt@Qd2eMS+hJeJ

stdin을 통해 형식으로 입력을 [m,n]받습니다. 결과를 0과 1의 목록으로 stdout에 인쇄합니다 (여기서 0 = V 및 1 = H).

온라인 테스트


설명:

J                           # J = 
 m             2            # map(lambda d: ..., range(2))
  m        t@Qd             # map(lambda k: ..., range(input[d] - 1))
   ,chk@Qdd                 # [(k + 1) / input[d], d]
                eMS+hJeJ    # print map(lambda x: x[-1], sorted(J[0] + J[-1])))

끝을 매핑 할 때 구문 맵 연산자를 사용하여 바이트를 저장할 수 있습니다. eM와 동일합니다 med.
Maltysen

또한, 당신은 그냥 걸릴 수 있습니다 @"VH"인쇄 할 수 있기 때문에 0하고 1대신 V하고 H.
Maltysen

로 인라인 할당을 사용하여 또 다른 바이트를 저장할 수 있습니다 J. 내가 지금까지 25 바이트에 가지고있는 것입니다 : pyth.herokuapp.com/…
Maltysen

@ Maltysen, jk출력 결과가 목록이 될 수 있으므로 제거 할 수 있다고 생각 합니다.
Tyilo

인라인 할당에 대한 내 의견을 볼 수 있습니다.
Maltysen

4

IA-32 기계 코드, 26 바이트

코드의 16 진 덤프 :

60 8b 7c 24 24 8d 34 11 33 c0 2b d1 74 08 73 03
03 d6 40 aa eb f2 61 c2 04 00

다음 C 코드에서 시작했습니다.

void doit(int m, int n, uint8_t* out)
{
    int t = m;
    while (true)
    {
        if (t >= n)
        {
            t -= n;
            *out++ = 1;
        }
        else
        {
            t += m;
            *out++ = 0;
        }
        if (t == n)
            break;
    }
}

제공된 버퍼에 출력을 기록합니다. 출력 길이를 반환하지는 않지만 실제로 필요하지는 않습니다. 출력 길이는 항상 m + n - 2:

int main()
{
    char out[100];
    int m = 10;
    int n = 3;
    doit(m, n, out);
    for (int i = 0; i < m + n - 2; ++i)
    {
        printf("%d ", out[i]);
    }
}

C 코드를 기계 코드로 변환하기 위해 먼저 가지 중 하나를 if/else비우고 0대신에 비교 하기 위해 약간의 조정 을 수행했습니다 n.

void doit(int m, int n, char* out)
{
    int t = n;
    while (true)
    {
        int r = 0;
        t -= m;
        if (t == 0)
            break;
        if (t >= 0)
        {
        }
        else
        {
            t += m + n;
            ++r;
        }
        *out++ = r;
    }
}

여기에서 인라인 어셈블리 코드 작성은 간단합니다.

__declspec(naked) void __fastcall doit(int x, int y, char* out)
{
    _asm
    {
        pushad;                 // save all registers
        mov edi, [esp + 0x24];  // edi is the output address
        lea esi, [ecx + edx];   // esi is the sum m+n
    myloop:                     // edx is the working value (t)
        xor eax, eax;           // eax is the value to write (r)
        sub edx, ecx;
        jz myout;
        jae mywrite;
        add edx, esi;
        inc eax;
    mywrite:
        stosb;                  // write one value to the output
        jmp myloop;
    myout:
        popad;                  // restore all registers
        ret 4;                  // return (discarding 1 parameter on stack)
    }
}

궁금합니다. 왜이 알고리즘이 작동합니까?
xnor

@xnor 비공식적으로, 그것은 fizzbuzz 순서를 추적합니다 . 여기 t에 "거리 buzz"가 있습니다. 거리가 적어도 경우 n, 이동 fizz, 다른 이동을 buzz; 거리를 업데이트하십시오. 0이 될 때까지 반복하십시오.
anatolyg

3

파이썬-125 바이트

매우 간단한 알고리즘을 사용하여 좌표를 증가시키고 선을 교차하여 인쇄 할 때이를 감지합니다. Pyth로 번역하려고합니다.

a,b=input()
i=1e-4
x=y=l=o=p=0
k=""
while len(k)<a+b-2:x+=i*a;y+=i*b;k+="V"*int(x//1-o//1)+"H"*int(y//1-p//1);o,p=x,y
print k

while 루프는 lines 수 를 확인한 다음 값을 빼서 int 경계를 넘 었는지 확인합니다.

39, 100stdin에서와 같은 입력을 가져 와서 인쇄합니다.HHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHH 한 줄에 표준 출력으로.


3

CJam, 15 바이트

Ll~_:*,\ff{%!^}

여기에서 시도하십시오.

인쇄 01V를 하고10 H에 .

설명

L          e# An empty list.
l~         e# Evaluate the input.
_:*,       e# [0, m*n).
\          e# The input (m and n).
ff{%!      e# Test if each number in [0, m*n) is divisible by m and n.
^}         e# If divisible by m, add an 10, or if divisible by n, add an 01 into
           e# the previous list. If divisible by neither, the two 0s cancel out.
           e# It's just for output. So we don't care about what the previous list
           e# is -- as long as it contains neither 0 or 1.

대각선은 전체 대각선의 1 / n마다 수평선을 교차하고 1 / m마다 수직선을 교차합니다.


이에 대한 설명을 추가 하시겠습니까? 그것은 매우 흥미 롭습니다. 그러나 적어도 초기 훑어보기에서 나는 그것이 왜 효과가 있는지 이해할 수 없습니다. 그것으로 재생하면서, 나는 그것이 문제의 설명에 주어진 상대 소수 값에만 작동하는 반면, 내 값은 모든 값에 작동한다는 것을 알았습니다. 따라서 기초 수학은 분명히 매우 다릅니다.
Reto Koradi

좀 더 들어가면 적어도 알고리즘 부분을 이해한다고 생각합니다. 나중에 출력 생성 로직을 연구해야합니다.
Reto Koradi

@RetoKoradi가 편집했습니다.
jimmy23013

2

TI-BASIC, 32

Prompt M,N
For(X,1,MN-1
gcd(X,MN
If log(Ans
Disp N=Ans
End

똑바로. 줄 바꿈으로 구분 된 0및 시퀀스를 사용합니다 1. TI-BASIC의 장점은 2 바이트 gcd(및 암시 적 곱셈이지만 단점은 종료 값과 입력에 소비 된 5 바이트를 포함하는 For 루프입니다.



1

하스켈, 78 바이트

import Data.List
m#n=map snd$sort$[(x,0)|x<-[1..m-1]]++[(y*m/n,1)|y<-[1..n-1]]

사용 예 :

*Main> 19 # 17
[0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]
*Main> 10 # 3
[0,0,0,1,0,0,0,1,0,0,0]

작동 방식 : [1,2, ..., m-1]에 (x,0)대한 모든 수직 교차점 의 x 값 목록 x( 0수직 표시)을 만들고에 (y*m/n,1)대한 모든 수평 교차점의 x 값 목록을 추가하십시오 y. [1,2, ..., n-1] (1 수평을 나타냄). 쌍의 두 번째 요소를 정렬하고 가져옵니다.

오늘의 저주 : 다시 표준 라이브러리 가 import아니기 때문에 17 바이트를 소비해야합니다 .sortData.List


1

KDB (Q), 44 바이트

{"HV"0=mod[asc"f"$1_til[x],1_(x*til y)%y;1]}

설명

교차점의 모든 x 축 값을 찾아 정렬합니다. mod 1이 "V"인 경우 0이 아닌 값은 "H"입니다.

테스트

q){"HV"0=mod[asc"f"$1_til[x],1_(x*til y)%y;1]}[5;3]
"VHVVHV"

1

CJam, 26 24 바이트

l~:N;:M{TN+Mmd:T;0a*1}*>

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

Bresenham 유형 알고리즘을 거의 직접 구현했습니다.

설명:

l~    Get input and convert to 2 integers.
:N;   Store away N in variable, and pop from stack.
:M    Store away M in variable.
{     Loop M times.
  T     T is the pending remainder.
  N+    Add N to pending remainder.
  M     Push M.
  md    Calculate div and mod.
  :T;   Store away mod in T, and pop it from stack
  0a    Wrap 0 in array so that it is replicated by *, not multiplied.
  *     Emit div 0s...
  1     ... and a 1.
}*      End of loop over M.
>       Pop the last 1 and 0.

01루프가 끝점까지 갔기 때문에 마지막 을 팝해야합니다. 이는 원하는 출력의 일부가 아닙니다. 우리가 할 수있는 참고 하지 단순히 위해, 그렇지 않으면 1으로 루프 수를 줄이고 N > M모든, 0우리는 맨 마지막을 제거 할 필요가있는 동안, 마지막 반복에서의이 누락됩니다 0.


1
당신은 사용할 수 있습니다 >에 대한 ;W<.
jimmy23013

좋은 생각이야. 1스택 맨 위에 있다는 것을 알고 있기 때문에 생산적으로 사용할 수도 있습니다.
Reto Koradi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.