ป้อนชื่อของคุณผ่าน D-pad


32

ปริศนา:

พิจารณาเกมคอนโซล / มือถือที่มี d-pad ที่คุณจะต้องป้อนชื่อแปลก ๆ สิ่งนี้ปรากฏในเกมรุ่นเก่าหลายเกมก่อนที่จะใช้ QWERTY เป็นที่นิยมในคอนโซล (เช่นฉันเชื่อว่า Wii ใช้รูปแบบแป้นพิมพ์ QWERTY สำหรับป้อนข้อมูล) โดยทั่วไปแป้นพิมพ์บนหน้าจอจะมีผลกับ *:

ค่าเริ่มต้น:

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z _ + ^ =

กรณีเปลี่ยน:

0 1 2 3 4 5 6 7 8 9
a b c d e f g h i j
k l m n o p q r s t
u v w x y z - + ^ =

นั่นคือปุ่มตัวอักษรและตัวเลขทั้งหมดและต่อไปนี้:

_: พื้นที่เดียว
-: ยัติภังค์
+: สลับตัวพิมพ์สำหรับตัวอักษรถัดไปเท่านั้น
^: สลับการล็อกตัวพิมพ์ใหญ่ (นั่นคือสลับตัวพิมพ์ของตัวอักษรทั้งหมด)
=: Enter, complete

* เห็นได้ชัดว่าฉันแทนที่คีย์เช่น "BKSP" และ "ENTER" ด้วยเวอร์ชันที่สั้นกว่า

และจากนั้นฮาร์ดแวร์จะรวมถึง D-pad (หรือบางรูปแบบของการควบคุมที่คุณสามารถไปup, down, leftและright)

โดยทั่วไปหน้าจอยังช่วยให้คุณย้ายจากด้านหนึ่งไปอีกด้านหนึ่งได้โดยตรง นั่นคือถ้าคุณกำลังเพ่งความสนใจไปที่ตัวอักษรJกดจะช่วยให้คุณที่จะย้ายไปยังตัวอักษรrightA

เมื่อใดก็ตามที่ฉันป้อนชื่อฉันจะพยายามหาวิธีที่รวดเร็วที่สุดในการทำเช่นนั้น

เป้าหมาย:

โปรแกรมของคุณจะป้อนสตริงซึ่งอาจรวมถึงตัวอักษรและตัวเลขรวมถึงช่องว่างและยัติภังค์และเป้าหมายของคุณคือการส่งออกจำนวนกดปุ่มที่สั้นที่สุดบน d-pad เพื่อส่งออกสตริงที่ต้องการ

การพิจารณา:

คุณไม่จำเป็นต้องรวมปุ่มกดสำหรับการกดตัวอักษรจริง
การโฟกัสเริ่มต้นที่A
Enter =จะต้องกดในตอนท้าย

ตัวอย่าง:

input: Code Golf
output: 43

อธิบาย:
A -> C= 2
C-> ^= 6 (เลื่อนไปทางซ้าย)
^-> o= 5
o-> d= 2
d-> e= 1
e-> += 5
+-> _= 1
_-> += 1
+-> G= 1 -> = 3
G-> o= 3
o-> l= 3
l-> f= 5
f-> == 6

โปรดทราบว่าการกดปุ่ม+สองครั้งเร็วกว่า_และGจะเป็นการกด^ครั้งเดียวแล้วสลับกลับ

การส่งที่ชนะ (ฉันจะให้อย่างน้อย 1w) จะเป็นทางออกที่สั้นที่สุด (เป็นไบต์) นี่เป็นคำถามแรกของฉันฉันหวังว่านี่จะชัดเจนและไม่ยากเกินไป


12
ท้าทายมาก! แค่จุดเดียว 48 ชั่วโมงอาจน้อยเกินไป นั่นคือระยะเวลาที่อนุญาตให้ใช้เงินดังนั้นมันควรจะมากกว่าสัปดาห์ +
Maltysen

@Maltysen ขอบคุณสำหรับคำแนะนำฉันได้อัปเดตการท้าทาย
Tas

1
คุณสามารถพันในแนวตั้งหรือแนวนอนได้หรือไม่?
Alex reinking

2
@ Alex พิจารณาว่าเป็นจุดที่ดี! ใช่คุณสามารถ.
Tas

ที่ดี! การใช้งานของฉันทำอย่างนั้นดังนั้นฉันแค่ต้องการตรวจสอบอีกครั้ง
อเล็กซ์ Reinking

คำตอบ:


5

ทับทิม (369 ไบต์)

รับอินพุตจากบรรทัดรับคำสั่ง

K="0123456789"+('A'..'Z').to_a.join+" +^="
Q=K.downcase.sub' ','-'
def d x,y
t,s=(x/10-y/10).abs,(x%10-y%10).abs
[t,4-t].min+[s,10-s].min
end
def v s,i,l,a
return l if s.empty?
c,r=s[0],s[1..-1]
j=K.index(c.upcase)||36
return v(r,j,l+d(i,j),a)if a.include?c
s,p=d(i,37)+d(37,j),d(i,38)+d(38,j)
[v(r,j,l+s,a),v(r,j,l+p,a==K ? Q : K)].min
end
puts v("#{ARGV[0]}=",10,0,K)

บันทึกเป็นจำนวนมากต้องขอบคุณ @Charlie :)


j=(K.index(c.upcase) or 36)สามารถถูกแทนที่ด้วยj=K.index(c.upcase)||36เพื่อบันทึก 4 ไบต์ def d(x,y)สามารถแทนที่ด้วยเพื่อประหยัดไบต์และเดียวกันจะไปสำหรับ def d x,y เพื่อไบต์อื่น On line ที่ผ่านมาสามารถถูกแทนที่ด้วยเพื่อบันทึก 1 ไบต์และมีการบันทึกไบต์อีก def vv(...) ifv(...)ifv(...)v ...true!!0
ชาร์ลี

ขอบคุณ! ฉันไม่รู้ทับทิมจริงๆ ฉันแปลสิ่งนี้จาก python ...
Alex Reinking

ฉันยังสามารถแทนที่&&ด้วย&และมี|| |
อเล็กซ์ Reinking

บรรทัดแรกของคุณ ( K=...) สามารถแทนที่ด้วยช่วง ( K='0123456789'+('A'..'Z').to_a.join+' +^=')
Charlie

โกนหนวดออกไปอีก 2 อัน!
อเล็กซ์ Reinking

9

Swift 1.2, 812 588 670 bytes

แก้ไข: ลบ 224 ไบต์โดยแทนที่อาร์เรย์ขนาดใหญ่ของตัวเลขด้วย Range และแปลงเป็น Array แทน

แก้ไข 2: เพิ่มการวนซ้ำในแนวตั้ง

typealias S=String
typealias I=Int
var A:(I)->S={S(UnicodeScalar($0))},B:(I)->(I,I)={a in(a%10,a/10)},a=Array(48...57).map{A($0)},b=[a+(Array(65...90)+[32,43,94,61]).map{A($0)},a+(Array(97...122)+[45,43,94,61]).map{A($0)}],z=Process.arguments
z.removeAtIndex(0)
func C(e:I,f:I)->I{let(a,b)=B(e),(c,d)=B(f)
return min(abs(d-b), abs(4-(d-b)))+min(abs(c-a),abs(10-(c-a)))}
func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->I{if count(c)==0{return C(e,39)}
let h=c.startIndex,i=c.endIndex,j=S(c[h])
if let k=find(b[f ?1:0],j){return C(e,k)+D(c[advance(h,1)..<i],k,(g ?(!f):f),false)}else{return min(C(e,37)+D(c,37,!f,true),C(e,38)+D(c,38,!f,false))}}
print(D(" ".join(z)))

ในการรันให้วางโค้ดใน.swiftไฟล์และรันด้วยswift <filename> <your name>


วิธีนี้ใช้วิธีการง่ายๆที่จัดเก็บ 'แป้นพิมพ์' สองชุดไว้เป็นอาร์เรย์

B:(I)->(I,I)={a in(a%10,a/10)} แปลงดัชนีจากอาร์เรย์เป็นตำแหน่ง x, y บนแป้นพิมพ์เสมือน

func C(e:I,f:I)->I{let(a,b)=B(e),(c,d)=B(f) return abs(d-b)+min(abs(c-a),abs(10-(c-a)))} รับดัชนีเริ่มต้น / สิ้นสุดและส่งกลับจำนวนขั้นต่ำของการย้ายเพื่อรับจากหนึ่งไปยังอีก (การบัญชีสำหรับการตัดแนวนอน)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->Iเป็นฟังก์ชั่นเรียกซ้ำที่ทำหน้าที่คำนวณส่วนใหญ่ มันจะคำนวณระยะทางจากตำแหน่งปัจจุบันไปยังตัวละครเป้าหมายเว้นแต่กรณีที่ควรเปลี่ยนจากนั้นก็จะคำนวณทั้งกะ และcaps lockวิธีการและใช้เวลาที่เล็กที่สุด

กำลังswift codegolf.swift Code Golfพิมพ์43


จำเป็นต้องคำนึงถึงการตัดตามแนวตั้ง
อเล็กซ์ Reinking

อัปเดตเป็นบัญชีสำหรับการตัดตามแนวตั้งด้วย
David Skrundz

4

Python 679 661 619 602 589 576 539 520 496 482 ไบต์

เรียกใช้สิ่งนี้และจะขออินพุต (โดยไม่มีข้อความแจ้ง) สำหรับการป้อนข้อมูลที่จะพิมพ์Code Golf43

a=input()+'=';b=0;c="0123456789abcdefghijklmnopqrstuvwxyz-+^=";d=0;e=[0,1];f='+';g='^';h=[i.isupper()or i==' 'for i in a];i=abs;p=lambda z:all([i==b for i in z]);q=0
def l(z):global s;k=c.index(z.lower().replace(' ','-'));s=[k%10,int(k/10)];m,n=s;return sum([min(i(m-e[0]),i(10-(m-e[0]))),min(i(n-e[1]),i(4-(n-e[1])))])
def o(z):global d,e;d+=l(z);e=s
for r in a:
 if p(h[q:q+3]):o(g);b^=1
 if p(h[q:q+2]):
  if l(f)<l(g):o(f)
  else:o(g);b^=1
 if p([h[q]]):o(f)
 o(r);q+=1
print(d)

โปรแกรมเต็มรูปแบบ:

input = input() + '='
capsOn = False

keys = "0123456789abcdefghijklmnopqrstuvwxyz-+^="
totalKeys = 0
caret = [0, 1]

shiftKey = '+'
capsKey = '^'

cases = [char.isupper() or char == ' ' for char in input]

def locate(char):
    """
        Find the location of the char on the keyboard
        regardless of case
    """
    location = keys.find(char.replace(' ', '-').lower())
    return [location % 10, int(location / 10)]


def dist(key):
    """
        Calculate the min dist to a char
    """
    nx, ny = locate(key)
    return sum([min(abs(nx - caret[0]), abs(10 - (nx - caret[0]))), min(abs(ny - caret[1]), abs(4 - (ny - caret[1])))])


def moveTo(char):
    """
        Move the caret to the char, ignoring case and
        adds the dist to the tally
    """
    global totalKeys, caret
    totalKeys = totalKeys + dist(char)

    print(keys[caret[0] + caret[1] * 10], '->', char, '=', dist(char))

    caret = locate(char)

diffCase = lambda case: all([i == capsOn for i in case])

for ind, ch in enumerate(input):
    if diffCase(cases[ind:ind + 3]): # use caps
        moveTo(capsKey)
        capsOn ^= 1
    elif diffCase(cases[ind:ind + 2]): # use closest
        if dist(shiftKey) < dist(capsKey):
            moveTo(shiftKey)
        else:
            moveTo(capsKey)
            capsOn ^= 1
    elif diffCase([cases[ind]]): # use shift
        moveTo(shiftKey)

    moveTo(ch) # apply the move

print('Total:', totalKeys)

เอาต์พุตเพิ่มเติมจากโปรแกรมแบบเต็ม:

Code Golf
a -> C = 2
c -> ^ = 6
^ -> o = 5
o -> d = 2
d -> e = 1
e -> + = 5
+ -> _ = 1
- -> + = 1
+ -> G = 3
g -> o = 3
o -> l = 3
l -> f = 5
f -> = = 6
Total: 43

บันทึกเป็นไบต์ด้วย @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 ขอบคุณ @Alex


ความช่วยเหลือใด ๆ ที่ชื่นชมในขณะที่ฉันยังเรียนรู้หลามและนี่คือรหัสกอล์ฟครั้งแรกของฉัน
J Atkin

คุณสามารถใช้ช่องว่างแทนการขีดเส้นใต้ในตารางภายในของคุณ
อเล็กซ์ Reinking

ฉันไม่ได้คิดอย่างนั้นขอบคุณ;)
J Atkin

3

C 675 ไบต์

รับอินพุตจากอาร์กิวเมนต์บรรทัดรับคำสั่ง ใช้หลักแบบเรียกซ้ำ:

#define Y(_) (!isdigit(_)?!isalpha(_)?3:1+(toupper(_)-65)/10:0)
#define X(_) (!isdigit(_)?!isalpha(_)?_-32&&_-45?_-43?9-(_==94):7:6:(toupper(_)-5)%10:_-48)
x,y,z;char*s;main(a,_,p,q,r){a<2?s[_]?!isdigit(s[_])&&((s[_]-32&&!isupper(s[_]))||!a)&&((s[_]-45&&!islower(s[_]))||a)?q=x,r=y,main(3,43),p=z,x=X(43),y=Y(43),main(3,s[_]),p+=z,x=X(s[_]),y=Y(s[_]),main(a,_+1),p+=z,x=q,y=r,main(3,94),q=z,x=X(94),y=Y(94),main(3,s[_]),q+=z,x=X(s[_]),y=Y(s[_]),main(!a,_+1),q+=z,z=(q<p?q:p):(main(3,s[_]),q=z,x=X(s[_]),y=Y(s[_]),main(a,_+1),z+=q):(main(3,61)):(a<3?s=((char**)_)[1],x=0,y=1,main(1,0),printf("%d",z):(x=X(_)-x,y=Y(_)-y,x+=10*(x<0),y+=4*(y<0),z=(x>5?10-x:x)+(y>2?4-y:y)));}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.