ลำดับการข้ามกริด


17

หากคุณนำกระดาษกราฟหนึ่งแผ่นและวาดเส้นที่ลาดเอียงที่ไปmหน่วยขวาและnหน่วยขึ้นคุณจะข้ามเส้นกริดn-1แนวนอนและm-1แนวตั้งในบางลำดับ เขียนรหัสเพื่อส่งออกลำดับที่

ตัวอย่างเช่นm=5และn=3ให้:

เส้นตารางข้ามสำหรับ m = 5, n = 3

อาจเกี่ยวข้องกับ: การสร้างจังหวะยูคลิด , การเอียง Fibonacci , FizzBuzz

อินพุต:สองจำนวนเต็มบวกm,nที่ค่อนข้างสำคัญ

เอาท์พุท:กลับหรือพิมพ์ข้ามเป็นลำดับของสองโทเค็นที่แตกต่างกัน ตัวอย่างเช่นมันอาจเป็นสตริงของHและVรายการTrueและFalseหรือ0ของและ1พิมพ์บนบรรทัดแยก อาจมีตัวคั่นระหว่างโทเค็นตราบใดที่มันยังคงเหมือนเดิมเสมอและไม่ใช่พูดว่าเป็นจำนวนช่องว่างที่แปรผัน

กรณีทดสอบ:

กรณีทดสอบแรกให้ผลลัพธ์ที่ว่างเปล่าหรือไม่มีผลลัพธ์

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

@RetoKoradi ไม่คุณไม่ควรรวมอินพุต ฉันใส่มันลงใน tuples เพื่อให้ง่ายต่อการประมวลผลกรณีทดสอบ
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)

และคำอธิบายว่าทั้งหมดทำงานอย่างไรโดยใช้รหัส Ruby เป็นแนวทาง:

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

Python 53

สิ่งนี้ใช้เอาต์พุตรายการจริง / เท็จ ไม่มีอะไรพิเศษที่นี่

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]กับรูปแบบ พิมพ์ผลลัพธ์ไปยัง stdout เป็นรายการของ 0 และ 1 โดยที่ 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

คุณสามารถรับ 23 ดูความคิดเห็นของฉันเกี่ยวกับการกำหนดแบบอินไลน์
Maltysen

4

รหัสเครื่อง IA-32 ขนาด 26 ไบต์

Hexdump ของรหัส:

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

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

ขณะที่วนรอบกำลังตรวจสอบจำนวนของlines แล้วตรวจสอบว่ามีค่าใดที่ผ่านขอบเขต int โดยการลบ

ใช้อินพุตเช่น39, 100จาก stdin และพิมพ์ออกมาเช่นHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHHHVHHVHHHVHHVHHHVHHVHHHVHH stdout ในหนึ่งบรรทัด


3

CJam, 15 ไบต์

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

ลองที่นี่

มันพิมพ์ 01สำหรับ V และ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คั่นด้วย linebreaks ข้อดีของ TI-BASIC คือการgcd(คูณสองไบต์และโดยนัย แต่ข้อเสียของมันคือ For loop ซึ่งรวมถึงค่าสิ้นสุดและ 5 ไบต์ที่ใช้สำหรับอินพุต



1

Haskell, 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]

วิธีการทำงาน: ทำรายการค่า x ของการข้ามแนวตั้งทั้งหมด(x,0)สำหรับxใน [1,2, ... , m-1] ( 0บ่งชี้แนวตั้ง) และผนวกรายการของค่า x ของการข้ามแนวนอนทั้งหมด(y*m/n,1)สำหรับyใน [1,2, ... , n-1] ( 1หมายถึงแนวนอน) จัดเรียงและใช้องค์ประกอบที่สองของคู่

คำสาปของวัน: อีกครั้งฉันต้องใช้เวลา 17 ไบต์importเพราะsortอยู่ในData.Listและไม่ได้อยู่ในห้องสมุดมาตรฐาน


1

KDB (Q), 44 ไบต์

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

คำอธิบาย

ค้นหาทั้งหมดxค่าแกนของจุดตัดกันและเรียงลำดับ ถ้า mod 1 เป็นศูนย์ "V", ไม่ใช่ศูนย์คือ "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

@ jimmy23013 ความคิดที่ดี เนื่องจากฉันรู้ว่าฉันมี1ด้านบนของสแต็คฉันก็อาจใช้มันอย่างมีประสิทธิผล
Reto Koradi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.