แยกตัวเลขออกเป็นสามเหลี่ยม


15

รับจำนวนเต็มn , แยกย่อยเป็นผลรวมของตัวเลขสามเหลี่ยมสูงสุด (โดยที่T mหมายถึงตัวเลขสามเหลี่ยมที่สามmหรือผลรวมของจำนวนเต็มจาก 1 ถึงm ) ดังนี้:

  • ในขณะที่n> 0 ,

    • พบที่ใหญ่ที่สุดที่เป็นไปได้จำนวนสามเหลี่ยมT เมตรเช่นที่T เมตรn

    • ผนวกเมตรเพื่อเป็นตัวแทนสามเหลี่ยมการสลายตัวของn

    • ลบT เมตรจากn

ตัวอย่างเช่นอินพุต44จะให้ผลลัพธ์ของ8311เนื่องจาก:

  • 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36 <44 แต่ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45> 44

    • ตัวเลขแรกคือ8 ; ลบ 36 จาก 44 เพื่อรับ8เหลือ
  • 1 + 2 + 3 = 6 <8 แต่ 1 + 2 + 3 + 4 = 10> 8

    • สองหลักเป็น3 ; ลบ 6 จาก 8 เพื่อให้เหลือ2
  • 1 <2 แต่ 1 + 2 = 3> 2

    • ตัวเลขที่สามและสี่จะต้องเป็น1และ1

ใช้ตัวเลข 1 ถึง 9 เพื่อแสดงตัวเลขสามเหลี่ยม 9 ตัวแรกจากนั้นใช้ตัวอักษร a ถึง z (สามารถเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก) เพื่อแทนตัวเลขสามเหลี่ยมที่ 10 ถึง 35 คุณจะไม่ได้รับข้อมูลที่จำเป็นสำหรับการใช้ "ตัวเลข" ที่ใหญ่กว่า

ขอบเขตของอินพุตคือ1 ≤ n <666และจะเป็นจำนวนเต็มเสมอ

อินพุตและเอาต์พุตที่เป็นไปได้ทั้งหมดและบางกรณีทดสอบที่เลือก (แสดงเป็นอินพุตจากนั้นเอาต์พุต):

1 1
2 11
3 2
4 21
5 211
6 3
100 d32
230 k5211
435 t
665 z731

ไม่จำเป็นต้องใช้เอาต์พุตสำหรับอินพุตของ-1/12 :)


แต่อินพุทของจำเป็นต้องมีเอาต์พุตของ of หรือไม่?
user75200

คำตอบ:


8

JavaScript (ES6), 52 ไบต์

f=(n,t=0)=>t<n?f(n-++t,t):t.toString(36)+(n?f(n):'')

อย่างไร?

แทนที่จะคำนวณอย่างชัดเจนT i  = 1 + 2 + 3 + … + iเราเริ่มต้นด้วยt = 0และลบt + 1ซ้ำ ๆจากnในขณะที่t <nเพิ่มtในแต่ละการวนซ้ำ เมื่อเงื่อนไขไม่เป็นจริงอีกต่อไปจำนวนT t ทั้งหมดจะถูกลบออกจากnและผลลัพธ์จะถูกอัพเดตตามนั้น เราทำซ้ำขั้นตอนจนกว่าn = 0

ด้านล่างนี้เป็นบทสรุปของการดำเนินงานทั้งหมดสำหรับn = 100

 n  |  t | t < n | output
----+----+-------+--------
100 |  0 | yes   | ""
 99 |  1 | yes   | ""
 97 |  2 | yes   | ""
 94 |  3 | yes   | ""
 90 |  4 | yes   | ""
 85 |  5 | yes   | ""
 79 |  6 | yes   | ""
 72 |  7 | yes   | ""
 64 |  8 | yes   | ""
 55 |  9 | yes   | ""
 45 | 10 | yes   | ""
 34 | 11 | yes   | ""
 22 | 12 | yes   | ""
  9 | 13 | no    | "d"
----+----+-------+--------
  9 |  0 | yes   | "d"
  8 |  1 | yes   | "d"
  6 |  2 | yes   | "d"
  3 |  3 | no    | "d3"
----+----+-------+--------
  3 |  0 | yes   | "d3"
  2 |  1 | yes   | "d3"
  0 |  2 | no    | "d32"

กรณีทดสอบ



4

dc, 74 ไบต์

?sa[2k_1K/1 4/la2*+v+0k1/dlardd*+2/-sadd10<t9>ula0<s]ss[87+P]st[48+P]sulsx

อันนี้แย่มาก

?sa             stores the input
[2k             sets precision to 2 so dc doesn't truncate 1/4
_1K/1 4/la2*+v+ uses the quadratic formula to find k, the next value to print
0k1/d           truncates k to an integer
lardd*+2/-sa    subtracts kth triangular number from the input 
dd10<t9>u       determines whether to print k as a letter or a digit         
la0<s]ss        loops when a is greater than 0
[87+P]st        prints k as a letter
[48+P]su        prints k as a digit (not p, as that leaves a trailing newline)
lsx             starts the main loop

3

JavaScript (ES6), 61 57 ไบต์

บันทึกแล้ว 4 ไบต์ขอบคุณ @Arnauld

f=(n,p=q=0)=>n?p-~q>n?q.toString(36)+f(n-p):f(n,++q+p):''

1
ฉันมีf=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld

@Arnauld โอ้ว้าวนั่นเป็นวิธีที่ดีกว่า คุณควรโพสต์ด้วยตัวคุณเอง ...
ETHproductions

1
Alright ในเวอร์ชันของคุณจะปลอดภัยไหมที่จะทำf=(n,p=q=0)และf(n,++q+p)?
Arnauld

@Annauld ใช่ขอบคุณ!
ETHproductions

2

Java 7, 81 ไบต์

int i=0;String c(int n){return i<n?c(n-++i):Long.toString(i,36)+(n>(i=0)?c(n):"");}

พอร์ตจาก@Arnauld 's ที่น่าตื่นตาตื่นใจ JavaScript (ES6) คำตอบ
แนวทางของฉันเองนั้นยาวเกือบ 2 เท่า ..

ลองที่นี่

คำอธิบาย:

int i=0;                  // Temp integer `i` (on class level)
String c(int n){          // Method with integer parameter and String return-type
  return i<n?             //  If `i` is smaller than the input integer
    c(n-++i)              //   Return a recursive call with input minus `i+1` (and raise `i` by 1 in the process)
   :                      //  Else:
    Long.toString(i,36)+  //   Return `i` as Base-36 +
     (n>(i=0)?            //   (If the input integer is larger than 0 (and reset `i` to 0 in the process)
      c(n)                //    Recursive call with the input integer
     :                    //   Else:
      "");                //    an empty String)
}                         // End of method

2

เรติน่า , 115 108 38 34 ไบต์

.+
$*¶
(\G¶|¶\1)+
0$1
+T`_w¶`w_`.¶

[ลองออนไลน์!] (รวมชุดทดสอบ) ใช้ตัวอักษรตัวพิมพ์ใหญ่ แก้ไข: บันทึกแล้ว70 74 ไบต์โดยการปรับคำตอบของ @ MartinEnder อย่างไร้ยางอายให้กับหมายเลขนี้เป็นรูปสามเหลี่ยมหรือไม่ คำอธิบาย: ตัวเลขจะถูกแปลงเป็น unary จากนั้นหมายเลขสามเหลี่ยมที่ใหญ่ที่สุดที่เป็นไปได้จะถูกจับคู่ซ้ำ ๆ จนกว่าจะหมดจำนวน แต่ละการแข่งขันจะถูกแปลงเป็นฐาน 36



0

R, 87 ไบต์

แต่เดิมฉันพยายามตั้งค่าตัวเลขสามเหลี่ยมที่เป็นไปได้ สิ่งนี้นำไปสู่รหัสนี้ด้วย 105 ไบต์:

pryr::f(n,{l=cumsum(1:35)
k=''
while(n){y=tail(which(l<=n),1)
n=n-l[y]
k=paste0(k,c(1:9,letters)[y])}
k})

สิ่งนี้ต้องการการจัดทำดัชนีเพิ่มเติมดังนั้นฉันจึงลองใช้วิธีการจาก @Arnauld เพื่อลดจำนวนไบต์ลงเหลือ 87

pryr::f(n,{k='';while(n){t=0;while(t<n){t=t+1;n=n-t};k=paste0(k,c(1:9,letters)[t])};k})

รหัสทั้งสองนี้ใช้ตัวอักษรที่ตั้งค่าไว้ล่วงหน้าเนื่องจากฉันไม่สามารถหาวิธีแปลงเป็นฐาน 36 ได้อย่างรวดเร็ว

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