Trình tự lưới chéo


17

Nếu bạn lấy một tờ giấy vẽ đồ thị và vẽ một đường dốc nghiêng mđơn vị sang phải và nđơn vị lên, bạn vượt qua các đường lưới n-1ngang và m-1dọc theo một số thứ tự. Viết mã để xuất chuỗi đó.

Ví dụ: m=5n=3đưa ra:

Đường lưới cắt ngang cho m = 5, n = 3

Có thể liên quan: Tạo nhịp điệu Euclidian , nghiêng Fibonacci , FizzBuzz

Đầu vào: Hai số nguyên dương m,ntương đối nguyên tố

Đầu ra: Trả lại hoặc in các giao cắt dưới dạng một chuỗi gồm hai mã thông báo riêng biệt. Ví dụ, nó có thể là một chuỗi HV, một danh sách TrueFalse, hoặc 0's và 1' s in trên dòng riêng biệt. Có thể có một dấu phân cách giữa các mã thông báo miễn là nó luôn giống nhau và không phải là số lượng không gian thay đổi.

Các trường hợp thử nghiệm:

Trường hợp thử nghiệm đầu tiên cho đầu ra trống hoặc không có đầu ra.

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

Trong định dạng (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
Hôm nay trên PPCG: Thuật toán vẽ đường của golf Bresenham
Sparr

Dựa trên định dạng thay thế mà bạn đã thêm, có thể / phải lặp lại đầu vào như một phần của đầu ra không? Mặt khác, tôi không hiểu tại sao đầu vào và đầu ra là một phần của cùng một danh sách.
Reto Koradi

@RetoKoradi Không, bạn không nên bao gồm đầu vào. Tôi đặt nó trong bộ dữ liệu để dễ dàng xử lý các trường hợp thử nghiệm.
xnor

Tôi có thể dự đoán câu trả lời, nhưng không thể hỏi được: sử dụng ký tự khoảng trắng làm một trong các mã thông báo đầu ra có được chấp nhận không? Một hậu quả sẽ là có thể có các khoảng trống đầu / cuối đáng kể trong đầu ra. Sẽ không có không gian khác, vì vậy tất cả các không gian sẽ rất quan trọng.
Reto Koradi

@RetoKoradi Không, vì không gian dấu vết không nhìn thấy được.
xnor

Câu trả lời:


7

Hồng ngọc, 92; Đà điểu 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%

Đầu ra cho cả hai sử dụng 1 và 0 (ví dụ 101101).


Đây là một lời giải thích của đà điểu:

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

Và một lời giải thích về cách toàn bộ hoạt động, sử dụng mã Ruby làm hướng dẫn:

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

Con trăn, 53

Điều này sử dụng đầu ra danh sách Đúng / Sai. Không có gì đặc biệt ở đây.

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

4

Số 1 - 32 24 byte

Jmm,chk@Qddt@Qd2eMS+hJeJ

Đưa đầu vào qua stdin với định dạng [m,n]. In kết quả ra thiết bị xuất chuẩn dưới dạng danh sách 0 và 1, trong đó 0 = V và 1 = H.

Kiểm tra nó trực tuyến


Giải trình:

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

Bạn có thể lưu một byte bằng cách sử dụng toán tử bản đồ cú pháp cho khi bạn kết thúc ánh xạ. eMcũng giống như med.
Maltysen

Ngoài ra, bạn chỉ có thể lấy ra @"VH"vì bạn được phép in 01thay vì VH.
Maltysen

Bạn có thể lưu một byte khác bằng cách sử dụng gán nội tuyến với J. Đây là những gì tôi có cho đến nay ở mức 25 byte: pyth.herokuapp.com/ Kẻ
Maltysen

@Maltysen, cảm ơn tôi nghĩ bạn có thể loại bỏ jkvì đầu ra có thể là một danh sách.
Tyilo

Bạn có thể nhận được 23 cái nhìn vào nhận xét của tôi về chuyển nhượng nội tuyến.
Maltysen

4

Mã máy IA-32, 26 byte

Mã thập phân của mã:

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

Tôi bắt đầu từ mã C sau:

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

Nó ghi đầu ra vào bộ đệm được cung cấp. Nó không trả về độ dài của đầu ra, nhưng nó không thực sự cần thiết: chiều dài đầu ra luôn là 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]);
    }
}

Để chuyển đổi mã C thành mã máy, trước tiên tôi đã thực hiện một số điều chỉnh, để làm cho một trong các if/elsenhánh trống và so sánh với 0thay vì 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;
    }
}

Từ đây, việc viết mã lắp ráp nội tuyến rất đơn giản:

__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)
    }
}

Tôi tò mò - tại sao thuật toán này hoạt động?
xnor

@xnor Một cách không chính thức, nó theo dõi chuỗi fizzbuzz . Đây tlà "khoảng cách đến buzz". Nếu khoảng cách ít nhất n, đi fizz, khác đi buzz; cập nhật khoảng cách; lặp lại cho đến khi nó 0.
anatolyg

3

Python - 125 byte

Sử dụng một thuật toán rất đơn giản, chỉ cần tăng tọa độ và phát hiện khi nó vượt qua các dòng và in ra. Đang tìm cách dịch sang 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

Vòng lặp while đó đang kiểm tra số lượng l và sau đó kiểm tra xem có bất kỳ giá trị nào đi qua một ranh giới int hay không bằng cách trừ đi.

Lấy đầu vào như 39, 100từ stdin và in ra như HHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHstdout trong một dòng.


3

CJam, 15 byte

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

Hãy thử nó ở đây.

Nó in 01cho V và10 cho H.

Giải trình

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.

Đường chéo cắt một đường ngang cho mỗi 1 / n của toàn bộ đường chéo và đi qua một đường thẳng đứng cho mỗi 1 / m.


Bạn sẽ thêm một lời giải thích cho điều này? Nó rất hấp dẫn, nhưng ít nhất là từ cái nhìn nhanh ban đầu tôi không hiểu tại sao nó hoạt động. Từ việc chơi với nó, tôi nhận thấy rằng nó chỉ hoạt động đối với các giá trị là các số nguyên tố tương đối (được đưa ra trong mô tả vấn đề), trong khi của tôi hoạt động cho tất cả các giá trị. Vì vậy, toán học cơ bản rõ ràng là rất khác nhau.
Reto Koradi

Sau khi để nó chìm trong một số chi tiết, tôi tin rằng tôi hiểu ít nhất là phần thuật toán. Phải nghiên cứu logic thế hệ đầu ra sau này.
Reto Koradi

@RetoKoradi Đã chỉnh sửa.
jimmy23013

2

TI-BASIC, 32

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

Nói thẳng ra. Sử dụng một chuỗi 01, được phân tách bằng dấu ngắt dòng. Ưu điểm của TI-BASIC là gcd(phép nhân hai byte và hàm ý, nhưng nhược điểm của nó là vòng lặp For bao gồm giá trị cuối và 5 byte dành cho đầu vào.



1

Haskell, 78 byte

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

Ví dụ sử dụng:

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

Cách thức hoạt động: tạo danh sách các giá trị x của tất cả các giao cắt dọc (x,0)cho xtrong [1,2, ..., m-1] ( 0biểu thị dọc) và nối thêm danh sách các giá trị x của tất cả các giao cắt ngang (y*m/n,1)cho ytrong [1,2, ..., n-1] ( 1biểu thị theo chiều ngang). Sắp xếp và lấy các yếu tố thứ hai của các cặp.

Lời nguyền của ngày: một lần nữa tôi phải tiêu tốn 17 byte cho importsortnó nằm trong Data.Listvà không có trong thư viện chuẩn.


1

KDB (Q), 44 byte

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

Giải trình

Tìm tất cả các giá trị trục x của các điểm giao nhau và sắp xếp chúng. Nếu mod 1 bằng 0 thì "V", khác không là "H".

Kiểm tra

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

1

CJam, 26 24 byte

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

Dùng thử trực tuyến

Rất đơn giản, khá nhiều việc thực hiện trực tiếp thuật toán loại Bresenham.

Giải trình:

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.

01Nhu cầu cuối cùng được bật lên vì vòng lặp đã đi đến điểm cuối, đây không phải là một phần của đầu ra mong muốn của anh ta. Lưu ý rằng chúng ta không thể đơn giản giảm số vòng lặp xuống 1. Nếu không, N > Mtất cả các 0s từ lần lặp cuối cùng sẽ bị thiếu, trong khi chúng ta chỉ cần thoát khỏi lần cuối cùng 0.


1
Bạn có thể sử dụng >cho ;W<.
jimmy23013

@ jimmy23013 Ý kiến ​​hay. Vì tôi biết rằng tôi có một 1thứ hạng cao nhất, tôi cũng có thể sử dụng nó một cách hiệu quả.
Reto Koradi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.