স্টারি মেটাগল্ফ


25

স্টারি একটি মজার মজাদার প্রোগ্রামিং ল্যাঙ্গুয়েজ +*.,`'যেখানে কোডগুলি কেবল যেখানে অন্তর্ভুক্ত থাকে সেই অক্ষরের প্রত্যেকটির দ্বারা প্রতিনিধিত্ব করা আসল কমান্ডটি তার সামনে স্পেসের সংখ্যা দ্বারা নির্ধারিত হয়। এটি গল্ফ ফিক্সড-আউটপুট চ্যালেঞ্জগুলির পক্ষেও জটিল করে তোলে, কারণ বিভিন্ন কমান্ডগুলি বিটগুলির বিস্তৃত পরিমাণের জন্য অ্যাকাউন্ট করতে পারে। বিশেষত, সংখ্যার আক্ষরিকের অবিচ্ছিন্ন উপস্থাপনা রয়েছে যা ছোটগুলিতে পরিচালনা করে বৃহত্তর সংখ্যা তৈরি করা প্রয়োজনীয় করে তোলে।

সুতরাং, এই চ্যালেঞ্জটি এমন একটি প্রোগ্রাম লেখার বিষয়ে যা এই জাতীয় স্টেরি প্রোগ্রামগুলি গল্ফ করতে পারে।

স্টারি কীভাবে কাজ করে?

(কয়েকটি বিশদ এএসল্যাংগুলিতে অনির্ধারিত রেখে গেছে, তাই আমি রুবি ইন্টারপ্রেটারের আচরণের সাথে যাচ্ছি ))

স্টারারি হ'ল স্ট্যাক-ভিত্তিক ভাষা, একক স্ট্যাকের স্বেচ্ছাসেবী-নির্ভুলতা পূর্ণসংখ্যার মানগুলি (যা প্রাথমিকভাবে খালি)।

একমাত্র অর্থপূর্ণ চরিত্রগুলি:

+*.,`'

এবং স্পেস। অন্য সমস্ত চরিত্র উপেক্ষা করা হয়। এই অ-স্থানের অক্ষরগুলির একটির পরে অনুসরণ করা স্পেসগুলির প্রতিটি ক্রম একক নির্দেশকে উপস্থাপন করে। নির্দেশের ধরণটি অ-স্পেস অক্ষর এবং স্পেসের সংখ্যার উপর নির্ভর করে ।

নির্দেশাবলী হ'ল:

Spaces  Symbol  Meaning
0         +     Invalid opcode.
1         +     Duplicate top of stack.
2         +     Swap top 2 stack elements.
3         +     Rotate top 3 stack elements. That is, send the top stack element
                two positions down. [... 1 2 3] becomes [... 3 1 2].
4         +     Pop and discard top of stack.
n ≥ 5     +     Push n − 5 to stack.
0 mod 5   *     Pop y, pop x, push x + y.
1 mod 5   *     Pop y, pop x, push x − y.
2 mod 5   *     Pop y, pop x, push x * y.
3 mod 5   *     Pop y, pop x, push x / y, rounded towards -∞.
4 mod 5   *     Pop y, pop x, push x % y. The sign of the result matches the sign of y.
0 mod 2   .     Pop a value and print it as a decimal number.
1 mod 2   .     Pop a value and print it as an ASCII character. This throws an error
                if the value is not in the range [0, 255].
n         `     Mark label n.
n         '     Pop a value; if non-zero, jump to label n. 

নোট করুন যে দণ্ডিতকারক মৃত্যুদন্ড কার্যকর হওয়ার আগে লেবেলের জন্য উত্স কোডটি স্ক্যান করে, সুতরাং সামনের দিকে পাশাপাশি পিছনের দিকে ঝাঁপানো সম্ভব।

অবশ্যই, স্টারির ইনপুট কমান্ডও রয়েছে (এর সাথে ,অ্যানালগালি ব্যবহার করে .) তবে সেগুলি এই চ্যালেঞ্জের জন্য অপ্রাসঙ্গিক।

চ্যালেঞ্জ

একটি স্ট্রিং দেওয়া হয়েছে, একটি স্টেরি প্রোগ্রাম উত্পন্ন করুন যা কোনও ইনপুট নেয় না এবং স্ট্রিংটি STDOUT এ প্রিন্ট করে।

আপনি STDIN (অথবা নিকটতম বিকল্প), কমান্ড-লাইন আর্গুমেন্ট বা ফাংশন আর্গুমেন্টের মাধ্যমে ইনপুট নিয়ে কোনও প্রোগ্রাম বা ফাংশন লিখতে এবং STDOUT (বা নিকটতম বিকল্প), ফাংশন রিটার্ন মান বা ফাংশন (আউট) প্যারামিটারের মাধ্যমে ফলাফল আউটপুট করতে পারেন।

আপনি ধরে নিতে পারেন যে স্ট্রিংটি 128 টি অক্ষরের বেশি নয় এবং এটি কেবল প্রিন্টযোগ্য ASCII অক্ষর (কোড পয়েন্ট 0x20 থেকে 0x7E) নিয়ে গঠিত।

আপনার সমাধানটি যুক্তিসঙ্গত ডেস্কটপ মেশিনে 5 মিনিটেরও কম সময়ে এই জাতীয় কোনও ইনপুট প্রক্রিয়াকরণ করা উচিত (এটির কিছুটা অবকাশ আছে; যদি আমার ল্যাপটপে এটি আরও কয়েক মিনিট সময় নেয় তবে আমার আপত্তি নেই, তবে যদি এটি 15 লাগে তবে আমি অযোগ্য ঘোষণা করব) এটা)।

আপনার সমাধানটি নীচে তালিকাভুক্ত বিভিন্ন স্ট্রিংয়ের উপর পরীক্ষা করা হবে। আপনার স্কোরটি সম্পর্কিত স্টারি প্রোগ্রামগুলির মোট বাইট গণনা। টাইয়ের ক্ষেত্রে, সংক্ষিপ্ততম মেটাগল্ফার জিতে। এটি হ'ল কোনও কোড না থাকলে আপনার নিজের কোডটি গল্ফ করবেন না (যা আমি মনে করি কেবলমাত্র সর্বাধিক সমাধান সম্ভব) case

নীচে তালিকাভুক্ত নির্দিষ্ট পরীক্ষার ক্ষেত্রে আপনার কোডটি অবশ্যই অপ্টিমাইজ করা উচিত নয়। বিশেষত, তাদের জন্য আপনার হাতে তৈরি করা সমাধানগুলি হার্ডকোড করা উচিত নয়। স্ট্রিংয়ের শ্রেণীর দিকে অনুকূলকরণ করা যার কাঠামোগুলি প্রদত্ত স্ট্রিংয়ের সাথে সমান is যদি আমি হার্ডকোডিং সমাধানগুলির কাউকে সন্দেহ করি তবে আমি কয়েকটি বা সমস্ত পরীক্ষার কেস (তুলনীয় কাঠামোর স্ট্রিং সহ) প্রতিস্থাপনের অধিকার সংরক্ষণ করি।

পরীক্ষার মামলা

প্রতিটি লাইন পৃথক পরীক্ষার কেস:

Hello, World!
pneumonoultramicroscopicsilicovolcanoconiosis
.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
Hickory, dickory, dock. The mouse ran up the clock. The clock struck 1. The mouse ran down. Hickory, dickory, dock.
36912059868043514648560046917066768694455682545071266675083273015450033938555319356951628735735013250100789433961153496780296165
bVZ48121347GLtpYnt76CZSxTpMDs6791EJE808077eySXldY162424ddTB90707UupwlWGb63618542VhA252989453TXrWgqGm85899uHOAY2oAKE198GOVUttvW63
7MYxoWBNt180CDHS5xBGvU70HHVB17bh8jYzIIiU6n6g98Rose1nOe8Svcg56nax20q30kT3Ttb2jHl5q2Iuf1vPbjPxm9cyKXwxc0OUK8pr13b2n7U9Y7RwQTc26A1I
n9}unwxVa}[rj+5em6K#-H@= p^X/:DS]b*Jv/_x4.a5vT/So2R`yKy=in7-15B=g _BD`Bw=Z`Br;UwwF[{q]cS|&i;Gn4)q=`!G]8"eFP`Mn:zt-#mfCV2AL2^fL"A

দ্বিতীয় পরীক্ষার মামলার ক্রেডিট ডেনিসে যায় । চতুর্থ পরীক্ষা মামলার ক্রেডিট Sp3000 এ যান।

রেফারেন্স সমাধান

এখানে সিজেএম-এ আসলেই একটি মৌলিক রেফারেন্স সমাধান রয়েছে:

q{S5*\iS*'+S'.}%

আপনি এটি এখানে পুরো টেস্ট স্যুইটের বিপরীতে চালাতে পারেন। স্কোরগুলি হ'ল:

1233
5240
4223
11110
7735
10497
11524
11392
Total: 62954

এটি সহজতম পদ্ধতির: প্রতিটি চরিত্রের কোড পয়েন্টকে আক্ষরিক হিসাবে চাপুন এবং তারপরে এটি মুদ্রণ করুন। এটি ধারাবাহিক অক্ষর, পূর্ণসংখ্যা মুদ্রণ, স্ট্রিংয়ের পুনরাবৃত্ত অংশ ইত্যাদির মধ্যে কোনও ছোট পার্থক্য ব্যবহার করে না I'll আমি সেই জিনিসগুলি আপনার কাছে রেখে দেব।

আমি বিশ্বাস করি উন্নতির জন্য অনেক জায়গা আছে। রেফারেন্সের জন্য, স্বল্পতম হস্তশিল্প "হ্যালো, ওয়ার্ল্ড!" মাত্র 169 বাইট দীর্ঘ।

উত্তর:


6

রুবি, 13461 10997

$s = {};
def shortest a,b=nil
    return $s[[a,b]] if $s[[a,b]]
    l = []
    if b
        if a == b
            return $s[[a,b]] = ""
        elsif a > b
            l.push shortest(a-b)+" *"
            l.push " +   *"+shortest(1,b) if a > 1
            l.push " + *"+shortest(0,b) if a > 0
            l.push "    +"+shortest(b)
        elsif a < b
            l.push " +  *"+shortest(a*a,b) if a*a>a && a*a<=b
            l.push " +*"+shortest(a+a,b) if a+a<=b && a+a>a
            l.push shortest(b-a)+"*"
            l.push " +"+shortest(a,b/a)+"  *" if a>2 && b%a == 0
            l.push " +"+shortest(a,b-a)+"*" if a>1 && b>a*2
        end
    else
        l.push ' '*(a+5)+'+' #if a < 6
        (1..a/2).each {|n|
            l.push shortest(n)+shortest(n,a)
        }
    end
    return $s[[a,b]] = l.min_by{|x|x.length}
end

def starry(str)
    arr = str.bytes.map{|b|
        if b>47 && b<58
            b-48# change digets to numbers
        else
            b
        end
    }

    startNum = (1..128).min_by{|x|arr.inject{|s,y|s + [shortest(x,y).length+2,shortest(y).length].min}+shortest(x).length}
    #one number to be put on the stack at the start.

    code = shortest(startNum)
    code += [
        shortest(arr[0]),
        " +"+shortest(startNum, arr[0])
    ].min_by{|x|x.length}

    arr.each_cons(2) do |a|
        pr = a[0]<10?'.':' .'
        code += [
            pr+shortest(a[1]),
            " +"+pr+shortest(a[0], a[1]),
            pr+" +"+shortest(startNum, a[1])
        ].min_by{|x|x.length}
    end
    code += arr[-1]<10?'.':' .'
end

a = ["Hello, World!",
"pneumonoultramicroscopicsilicovolcanoconiosis",
".oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.",
"Hickory, dickory, dock. The mouse ran up the clock. The clock struck 1. The mouse ran down. Hickory, dickory, dock.",
"36912059868043514648560046917066768694455682545071266675083273015450033938555319356951628735735013250100789433961153496780296165",
"bVZ48121347GLtpYnt76CZSxTpMDs6791EJE808077eySXldY162424ddTB90707UupwlWGb63618542VhA252989453TXrWgqGm85899uHOAY2oAKE198GOVUttvW63",
"7MYxoWBNt180CDHS5xBGvU70HHVB17bh8jYzIIiU6n6g98Rose1nOe8Svcg56nax20q30kT3Ttb2jHl5q2Iuf1vPbjPxm9cyKXwxc0OUK8pr13b2n7U9Y7RwQTc26A1I",
"n9}unwxVa}[rj+5em6K#-H@= p^X/:DS]b*Jv/_x4.a5vT/So2R`yKy=in7-15B=g _BD`Bw=Z`Br;UwwF[{q]cS|&i;Gn4)q=`!G]8\"eFP`Mn:zt-#mfCV2AL2^fL\"A"]
c = a.map{
    |s|
    starry(s).length
}
p c.inject(0){|a,b|a+b}

পদ্ধতিটি starryপ্রদত্ত প্রশ্নের উত্তর দেয়।

ফলাফল:

230
639
682
1974
1024
1897
2115
2436
Total: 10997

কিভাবে এটা কাজ করে

shortestপ্রধান অ্যালগরিদম হয়। এটি একটি সংখ্যা নিয়েছে এবং স্ট্যাকের উপরে রাখার সবচেয়ে সংক্ষিপ্ততম উপায় এটি আবিষ্কার করে, বা এটি দুটি সংখ্যা নেয় এবং প্রথমটি ইতিমধ্যে চালু রয়েছে ধরে নিয়ে স্ট্যাকের উপর দ্বিতীয়টি রাখার জন্য কোড ফেরত দেয়। $sআরও ব্যবহারের জন্য এই ক্রিয়াকলাপগুলির ফলাফল রাখা একটি হ্যাশ।

starryএকটি স্ট্রিং নেয় এবং এটিকে অক্ষর কোডের অ্যারেতে বিভক্ত করে (বা হজমের সংখ্যাগুলি)। এটি স্ট্যাকের নীচে এক নম্বর দিয়ে কোড শুরু করে। এরপরে এটি সংক্ষিপ্ততম উপায়ে গণনা করে যে এটি প্রতিটি ক্রমাগত সংখ্যা উত্পন্ন করতে পারে, সম্ভবত শেষটি অনুলিপি করে বা শুরুতে স্ট্যাকের উপরে রাখা নম্বরটি ব্যবহার করে।


9

পাইথন 3, 17071 11845

from functools import lru_cache
import heapq
import time

cases = r"""
Hello, World!
pneumonoultramicroscopicsilicovolcanoconiosis
.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
Hickory, dickory, dock. The mouse ran up the clock. The clock struck 1. The mouse ran down. Hickory, dickory, dock.
36912059868043514648560046917066768694455682545071266675083273015450033938555319356951628735735013250100789433961153496780296165
bVZ48121347GLtpYnt76CZSxTpMDs6791EJE808077eySXldY162424ddTB90707UupwlWGb63618542VhA252989453TXrWgqGm85899uHOAY2oAKE198GOVUttvW63
7MYxoWBNt180CDHS5xBGvU70HHVB17bh8jYzIIiU6n6g98Rose1nOe8Svcg56nax20q30kT3Ttb2jHl5q2Iuf1vPbjPxm9cyKXwxc0OUK8pr13b2n7U9Y7RwQTc26A1I
n9}unwxVa}[rj+5em6K#-H@= p^X/:DS]b*Jv/_x4.a5vT/So2R`yKy=in7-15B=g _BD`Bw=Z`Br;UwwF[{q]cS|&i;Gn4)q=`!G]8"eFP`Mn:zt-#mfCV2AL2^fL"A
""".strip().splitlines()

@lru_cache(maxsize=128)
def shortest_m_to_n(m, n):
    if m is None:
        L = []
    else:
        L = [m]

    to_search = [[0, "", L]]
    seen = set()

    while True:
        length, code, stack = heapq.heappop(to_search)

        if len(stack) == 1 and stack[-1] == n:
            return code

        seen.add(tuple(stack))
        options = []

        for i in range(1, 11):
            new_stack = stack[:] + [i]
            new_code = code + ' '*(i+5) + '+'
            options.append([len(new_code), new_code, new_stack])

        if stack:
            new_stack = stack[:] + [stack[-1]]
            new_code = code + " +"
            options.append([len(new_code), new_code, new_stack])

        if len(stack) >= 2:
            x, y = stack[-2:]

            for i, op in enumerate(['+', '-', '*', '//', '%']):
                try:
                    new_elem = eval("{}{}{}".format(x, op, y))
                    new_stack = stack[:-2] + [new_elem]
                    new_code = code + ' '*i + '*'
                    options.append([len(new_code), new_code, new_stack])

                except ZeroDivisionError:
                    pass

        for op in options:
            if tuple(op[2]) in seen or len(op[2]) > 4 or op[2][-1] > 200:
                continue

            heapq.heappush(to_search, op)

def lcs(s1, s2):
    dp_row = [""]*(len(s2)+1)

    for i, c1 in enumerate(s1):
        new_dp_row = [""]

        for j, c2 in enumerate(s2):
            if c1 == c2 and not c1.isdigit():
                new_dp_row.append(dp_row[j] + c1)
            else:
                new_dp_row.append(max(dp_row[j+1], new_dp_row[-1], key=len))

        dp_row = new_dp_row

    return dp_row[-1]

def metagolf(s):
    keep = ""
    split_index = 0

    for i in range(1, len(s)):
        l = lcs(s[:i], s[i:][::-1])
        if len(l) > len(keep):
            keep = l
            split_index = i

    code = []
    stack = []
    keep_ptr = 0
    i = 0

    while i < len(s):
        c = s[i]
        n = ord(c)

        if c in "0123456789":
            code += [" "*(int(c)+5) + "+."]
            i += 1
            continue

        if stack:
            if stack[-1] == n:
                code += [" +", " ."]
            elif len(stack) >= 2 and stack[-2] == n:
                for j in range(len(code)):
                    if code[~j] == " +":
                        code[~j] = ""
                        break

                code += [" +", " ."]
                stack.pop()
            else:
                code += [shortest_m_to_n(stack[-1], n), " +", " ."]
                stack[-1] = n

        else:
            code += [shortest_m_to_n(None, n), " +", " ."]
            stack.append(n)

        while i < split_index and keep[keep_ptr:][:1] == c:
            code += [" +"]
            keep_ptr += 1
            stack.append(n)

        i += 1

    code = "".join(code)

    if code[-4:] == " + .":
        code = code[:-4] + " ."

    return code

total = 0

for case in cases:
    start_time = time.time()

    s = metagolf(case)
    print(len(s), time.time() - start_time)
    total += len(s)
    print(s)
    print('='*50)

print(total)

প্রাসঙ্গিক ফাংশনটি যথাযথভাবে নামকরণ করা হয় metagolf

ফলাফলগুলি হ'ল:

210
676
684
2007
1463
2071
2204
2530
Total: 11845

আপনি এখানে পুরো আউটপুট খুঁজে পেতে পারেন ।

সংক্ষিপ্ত বর্ণনা

আমি ব্যাখ্যা সংক্ষিপ্ত রাখতে যাচ্ছি যেহেতু এখনও অনেক কিছুই উন্নত করা উচিত।

বেসিক অ্যালগরিদম কেবল চরগুলির জোড়া দেখায় এবং বিএফএসের মাধ্যমে একটি চর থেকে অন্য চরে স্থানান্তরিত করার সর্বোত্তম উপায় খুঁজে পায়। অঙ্কগুলি বর্তমানে তাত্ক্ষণিকভাবে ধাক্কা এবং মুদ্রণ করা হয়, যদিও এটি পরে পরিবর্তিত হবে।

কিছুটা দীর্ঘতম-সাধারণ-অনুচ্ছেদও চলছে, পরে পুনরায় ব্যবহারের জন্য স্ট্যাকের কয়েকটি উপাদান রেখে। এটি পুনরাবৃত্তির মতো ভাল নয়, তবে ভাল সঞ্চয় সরবরাহ করে।


হুরয়ে, যুদ্ধের জন্য কেউ :-) অবশ্যই, এখন আমি দেখতে পাচ্ছি যে আমার অনেক দীর্ঘ পথ যেতে হবে ...
ETH প্রোডাকশনস

5

জাভাস্ক্রিপ্ট, 25158 23778

এখন ES5- সামঞ্জস্যপূর্ণ!

String.prototype.repeat = String.prototype.repeat || function (n) { return Array(n+1).join(this); }

function starrify(x) {
  function c(x){return x.charCodeAt()}
  var char = x[0], result = ' '.repeat(c(char)+5)+'+ + .';
  x=x.slice(1);
  for(var i in x) {
    if (char < x[i]) {
      result += ' '.repeat(c(x[i])-c(char)+5)+'+* + .';
    } else if (char > x[i]) {
      if(c(char)-c(x[i]) < c(x[i])) {
        result += ' '.repeat(c(char)-c(x[i])+5)+'+ * + .';
      } else {
        result += ' '.repeat(c(x[i])+5)+'+ + .';
      }
    } else {
      result += ' + .';
    }
    char = x[i];
  }
  return result;
}

ফলাফল:

432
949
2465
3996
1805
3551
5205
5375
Total: 23778

আমার মতে একটি ভাল শুরু, তবে স্পষ্টতই শেষ হয়নি। পৃথকভাবে প্রতিটি চর তৈরির পরিবর্তে এটি পূর্বের চর কোড থেকে যোগ বা বিয়োগ করে। আমি যখন মেটা-গল্ফিং করি তখন আমি একটি সম্পূর্ণ ব্যাখ্যা যুক্ত করব।


হ্যাঁ, এটি এখন ফায়ারফক্সে কাজ করে, যদিও ক্রোম এখনও অভিযোগ করে charCodeAt
মার্টিন ইন্ডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.