ภาษาที่ไม่ จำกัด


28

ประเภทใดประเภทหนึ่งที่ชื่นชอบความท้าทายบนเว็บไซต์นี้เป็นความท้าทาย ความท้าทายเหล่านี้กำหนดข้อ จำกัด ที่คอมพิวเตอร์จัดการได้ซึ่งแหล่งที่มาของคำตอบที่อาจเกิดขึ้นต้องผ่าน ฉันชอบความท้าทายเหล่านี้มากฉันทำงานเกี่ยวกับภาษากอล์ฟที่ออกแบบมาเพื่อเอาชนะความท้าทายเหล่านี้มาระยะหนึ่งแล้ว ตอนนี้ฉันต้องการขยายความท้าทายให้กับคุณ งานของคุณคือการออกแบบภาษาเพื่อแก้ปัญหาแหล่งงานที่ จำกัด คุณจะมีเวลาในการออกแบบและใช้งานภาษาซึ่งการเปลี่ยนแปลง ณ จุดและส่วนเพิ่มเติมใหม่จะไม่สามารถแข่งขันได้และการส่งทั้งหมดจะไปพบกันในการทดสอบความท้าทาย

เกณฑ์การให้คะแนน

ก่อนที่จะโพสต์ความท้าทายฉันจะมาพร้อมกับรายการความท้าทายง่ายๆในการแก้ปัญหาและรายการข้อ จำกัด ของแหล่งที่มาที่ต้องติดตาม สำหรับการจับคู่ความท้าทายและข้อ จำกัด แหล่งที่มาแต่ละภาษาของคุณสามารถรับได้ระหว่าง 0 ถึง 2 คะแนน (จะมีความท้าทาย 10 ข้อและข้อ จำกัด 10 ข้อที่นำไปสู่การรวมกันทั้งหมด 100 ครั้ง) คะแนนภาษา

  • 1 point หากสามารถทำงานให้เสร็จสมบูรณ์โดยมีข้อ จำกัด น้อยกว่า 150 ไบต์
  • 2 คะแนนหากการแก้ปัญหาเป็นทางออกที่สั้นที่สุดของการแข่งขันภาษาใด ๆ (ทั้งสองภาษาจะได้คะแนน 2 คะแนนในกรณีที่เสมอกัน)
  • 0 คะแนนหากพวกเขาไม่สามารถสร้างโปรแกรมที่ทำงานให้เสร็จสมบูรณ์ภายใต้ข้อ จำกัด น้อยกว่า 150 ไบต์

คะแนนของคุณจะเป็นผลรวมของคะแนนทั้งหมดที่ได้รับในทุกการแข่งขันที่เป็นไปได้ เป้าหมายคือเพื่อให้ได้คะแนนสูงสุด คนอื่น ๆ อาจช่วยคุณตีกอล์ฟโซลูชันของคุณสำหรับความท้าทายและปรับปรุงคะแนนของคุณ

ฉันจะเปิดเผย 4 รายการของแต่ละรายการเมื่อทำการโพสต์และเพิ่มอีก 8 หนึ่งสัปดาห์หลังจากคำตอบที่สอง คุณจะได้รับอนุญาตให้ทำคะแนน 1 คะแนน (การส่งสั้นที่สุดจะไม่นับ) ในการจับคู่ที่มีการเปิดเผยทั้งสองส่วนก่อนสัปดาห์แรก วิธีนี้คุณจะได้รับความคิดว่าภาษาของคุณดีขึ้นได้อย่างไรในขณะที่คุณกำลังทำอยู่ แต่คุณไม่สามารถออกแบบภาษาของคุณเพื่อสร้างความท้าทายและข้อ จำกัด ทั้งหมดได้

ฉันจะรวมแฮชของหมวดหมู่ที่ตั้งใจไว้กับคำถามเพื่อให้คุณมั่นใจได้ว่าฉันจะไม่เปลี่ยนแปลงหมวดหมู่เหล่านั้นในช่วงสัปดาห์เพื่อผลประโยชน์ของฝ่ายใดฝ่ายหนึ่ง นอกจากนี้ฉันจะไม่บอกทุกคนถึงพารามิเตอร์ที่ซ่อนไว้จนกว่าสัปดาห์จะขึ้นหรือแข่งขันในการท้าทายตัวเอง

ภาษาที่มีอยู่ก่อน

ความท้าทายนี้เปิดสำหรับทุกภาษาที่มีอยู่แล้วอย่างไรก็ตามหากคุณไม่ใช่ผู้เขียนภาษาโปรดตอบชุมชนวิกิเพื่อให้สมาชิกคนอื่น ๆ ในชุมชนของเรามีส่วนร่วมในการให้คะแนนโดยตรง การตั้งค่าสถานะบรรทัดคำสั่งไม่จำเป็นต้องปฏิบัติตามข้อ จำกัด ใด ๆ อย่างไรก็ตามทุกโปรแกรมควรรันด้วยอาร์กิวเมนต์บรรทัดคำสั่งเดียวกัน (เช่นคุณควรเลือกหนึ่งรายการและติดกับ) สิ่งเหล่านี้ไม่ได้เพิ่มในจำนวนไบต์ของคุณ

ความท้าทายและข้อ จำกัด

มีการบังคับใช้ข้อ จำกัด ในการเข้ารหัส ASCII ของไบนารีของคุณโดยไม่คำนึงถึงหน้ารหัสที่คุณใช้ ลิงก์เหล่านี้บางส่วนไปยังคำถามที่มีอยู่บนไซต์ซึ่งพวกเขาได้รับข้อกำหนด io สำหรับความท้าทายและข้อ จำกัด ของแหล่งที่มาสำหรับข้อ จำกัด คุณสามารถเพิกเฉยต่อสิ่งใด ๆ ที่ "ห้ามบิลด์อิน" หรือเอาชนะเมตาดาต้าที่มีอยู่ในความท้าทายใด ๆ ที่เชื่อมโยง

เพื่อเป็นการเตือน: อย่าพยายามควบคุมทนาย ฉันรู้ว่ามันเป็นการแข่งขัน แต่เป็นเพราะมีความท้าทายย่อยต่างกัน 100 ประการและฉันก็ไม่สามารถรับประกันได้ว่าพวกเขาทั้งหมดจะไม่มีปัญหา แค่พยายามมีความสุข

ความท้าทาย

ข้อ จำกัด

เกณฑ์ที่เหลือมีแฮช sha512 จาก:

4de5eca33c6270798606cf1412820c4ce112d8b927ef02877f36795b2b15ffacca51ea598fa89b8d6bc9f4cde53810e0e7ade30e536e52e28f40a6a13841dfc5  -

ขอให้เรายังคงอภิปรายนี้ในการแชท
ข้าวสาลีตัวช่วยสร้าง

1
มาที่นี่เพื่อลงคะแนนแล้วอ่านข้อมูลจำเพาะ +1
trichoplax

3
จะเกิดอะไรขึ้นถ้าฉันพัฒนาภาษาที่โปรแกรมว่างเรียงลำดับรายการจำนวนเต็มพิมพ์ hello world กำหนดว่าวงเล็บมีความสมดุลหรือการทดสอบแบบดั้งเดิมขึ้นอยู่กับว่ามีอะไรอยู่ในอินพุต ฉันขอแนะนำให้เก็บความท้าทายเหล่านี้เป็นเพียงตัวอย่างเท่านั้นและให้คะแนนการส่งเฉพาะความท้าทายอื่น ๆ ที่ยังไม่ได้เปิด
Leo

1
ขอให้เรายังคงอภิปรายนี้ในการแชท
ข้าวสาลีตัวช่วยสร้าง

1
@ComradeSparklePony แฟล็กบรรทัดคำสั่งจำเป็นต้องเหมือนกันสำหรับโปรแกรมทั้งหมด
ข้าวสาลี Wizard

คำตอบ:


5

ความกว้าง

ล่ามยังอยู่ในระหว่างดำเนินการ (ฉันยังคงมีสล็อตคำสั่งที่ไม่ได้ใช้อยู่หลายช่อง) ซื้อคืนภาคมีเอกสารเพิ่มเติมสามารถพบได้ที่นี่

เดนนิสเพิ่มความกว้างให้กับ TIO น้อยกว่าหนึ่งนาทีที่ผ่านมา: ลองออนไลน์!

ความกว้างเป็นภาษาสแต็คตามลึกลับผมพัฒนาขึ้นเมื่อเร็ว ๆ นี้ในความคิดแรกที่ผมทิ้งในคำถามนี้ มันขึ้นอยู่กับความกว้างมากหรือน้อยตัวอักษรอยู่ในแบบอักษร "ปกติ" อักขระเท่านั้นที่ทำทุกอย่างคือตัวอักษรตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก อักขระอื่น ๆ ทั้งหมดจะถูกละเว้น ฉันแบ่งตัวอักษรออกเป็น 10 หมวดหมู่ความกว้างที่แตกต่างกันซึ่งเป็นรูปแบบของการดำเนินการ 10 อย่างที่เป็นไปได้ในความกว้าง:

0: i j l                     # do while counter > 0
1: f r t I                   # end
2: c k s v x y z J           # 0 in commands
3: a b d e g h n o p q u L   # separator (no-op)
4: F T Z                     # push base 10 number, using left side row titles (width numbers); terminated with original char
5: A B E K P S V X Y         # 1 in commands
6: w C D H N R U             # 2 in commands
7: G O Q                     # push string literal; sets of 2 width numbers equate to index in printable ASCII; terminated with original char
8: m M                       # if top of stack
9: W                         # else

2, 5และ6ให้การเข้าถึงคำสั่งซึ่งส่วนใหญ่โต้ตอบกับสแต็ก ข้อมูลเพิ่มเติมสามารถดูได้ที่info.txtหน้าใน repo Github

นี่คือรหัส Python ของล่าม ฉันยังคงมีหลายคำสั่งให้เพิ่มและฉันกำลังพิจารณาว่าจะทำงานกับการจัดการข้อผิดพลาดได้อย่างไร (ฉันจะเพิ่มการตั้งค่าสถานะในบางจุดเพื่อให้การทดสอบด้วยไวยากรณ์ที่เป็นนามธรรมมากขึ้นเพราะมิฉะนั้นภาษานี้เป็นความเจ็บปวดยักษ์ที่จะทำงานด้วย)

import sys
import math
import numbers
import functools

try:
    file = sys.argv[1]
except IndexError:
    file = "source.wide"

with open(file) as f:
    source = f.read()

translation = ("ijl", "frtI", "cksvxyzJ", "abdeghnopquL", "FTZ", "ABEKPSVXY", "wCDHNRU", "GOQ", "mM", "W")
chars = "".join(sorted("".join(translation)))
strings = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n\t"""


def trans(letter):
    for each in translation:
        if letter in each:
            return translation.index(each)

COMMAND = "COMMAND"
COMMANDS = (2, 5, 6)
NUMBER = "NUMBER"
STRING = "STRING"
DO = "DO"
IF = "IF"
ELSE = "ELSE"
END = "END"
SEPARATOR = "SEPARATOR"


class Token:
    def __init__(self, val, type_):
        self.val = val
        self.type = type_


class Lexer:
    def __init__(self, src):
        self.src = src
        self.pos = 0
        self.char = self.src[self.pos]

    def read(self):
        if self.char is None:
            return None

        command = trans(self.char)

        if command == 0:
            self.advance()
            return Token(0, DO)
        elif command == 1:
            self.advance()
            return Token(1, END)
        elif command == 3:
            self.advance()
            return Token(3, SEPARATOR)
        elif command == 4:
            return self.read_num()
        elif command == 7:
            return self.read_str()
        elif command == 8:
            self.advance()
            return Token(8, IF)
        elif command == 9:
            self.advance()
            return Token(9, ELSE)
        else:
            return self.read_cmd()

    def advance(self):
        self.pos += 1

        try:
            self.char = self.src[self.pos]
        except IndexError:
            self.char = None

    def read_num(self):
        delim = self.char
        self.advance()

        res = ""
        while self.char is not None and self.char != delim:
            res += str(trans(self.char))
            self.advance()

        self.advance()

        return Token(int(res), NUMBER)

    def read_str(self):
        def read_char():
            res_ = str(trans(self.char))
            self.advance()
            res_ += str(trans(self.char))
            self.advance()
            try:
                return strings[int(res_)]
            except IndexError:
                return " "

        delim = self.char
        self.advance()

        res = ""
        while self.char is not None and self.char != delim:
            res += read_char()

        self.advance()

        return Token(res, STRING)

    def read_cmd(self):
        command = ""
        while self.char is not None and trans(self.char) in COMMANDS and len(command) <= 4:
            command += str(COMMANDS.index(trans(self.char)))
            self.advance()

        return Token(command, COMMAND)

source = "".join(filter(lambda c: c in chars, source))

stack = []
backburner = []
counter = 0


def set_counter(val):
    global counter
    counter = int(val)

    if counter < 0:
        counter = 0


def set_stack(val):
    global stack
    stack = val


def num_input():
    inp = input()
    try:
        stack.append(int(inp))
    except ValueError:
        try:
            stack.append(float(inp))
        except ValueError:
            pass


def flip_ends():
    if len(stack) > 1:
        stack[0], stack[-1] = stack[-1], stack[0]


def clear_stack():
    global stack
    stack = []


def reload_stack(is_top):
    global backburner, stack

    if is_top:
        stack.extend(backburner)
    else:
        stack = backburner + stack

    backburner = []


# https://stackoverflow.com/a/15285588/7605753
def is_prime(n):
    if n == 2 or n == 3:
        return True
    if n < 2 or n % 2 == 0:
        return False
    if n < 9:
        return True
    if n % 3 == 0:
        return False
    r = int(math.sqrt(n))
    _f = 5
    while _f <= r:
        if n % _f == 0:
            return False
        if n % (_f + 2) == 0:
            return False
        _f += 6
    return True


def error():
    raise Exception

commands = {
    "0": lambda: stack.append(stack[-1]),
    "1": lambda: stack.append(stack.pop(-2)),
    "2": lambda: stack.pop(),
    "00": lambda: set_counter(stack[-1]),
    "01": lambda: stack.append(len(stack)),
    "02": lambda: stack.append(input()),
    "10": num_input,
    "11": lambda: stack.append(str(stack.pop())),
    "12": lambda: stack.append(int(stack.pop())),
    "20": lambda: set_counter(counter + 1),
    "21": lambda: set_counter(counter - 1),
    "22": lambda: print(stack.pop()),
    "000": lambda: stack.append(float(stack.pop())),
    "001": lambda: stack.append(-stack.pop()),
    "002": lambda: stack.append(not stack.pop()),
    "010": lambda: stack.append(stack.pop(-2) + stack.pop()),
    "011": lambda: stack.append(stack.pop(-2) - stack.pop()),
    "012": lambda: stack.append(stack.pop(-2) / stack.pop()),
    "020": lambda: stack.append(stack.pop(-2) // stack.pop()),
    "021": lambda: stack.append(stack.pop(-2) * stack.pop()),
    "022": lambda: stack.append(stack.pop(-2) % stack.pop()),
    "100": lambda: stack.append(math.factorial(stack.pop())),
    "101": lambda: stack.append(str(stack.pop(-2)) + str(stack.pop())),
    "102": lambda: stack.append(math.pow(stack.pop(-2), stack.pop())),
    "110": lambda: stack.append(math.sqrt(stack.pop())),
    "111": lambda: stack.append(math.log(stack.pop(-2), stack.pop())),
    "112": lambda: stack.append(~stack.pop()),
    "120": lambda: stack.append(stack.pop(-2) | stack.pop()),
    "121": lambda: stack.append(stack.pop(-2) & stack.pop()),
    "122": lambda: stack.append(stack.pop(-2) << stack.pop()),
    "200": lambda: stack.append(stack.pop(-2) >> stack.pop()),
    "201": lambda: stack.append(stack.pop(-2)[stack.pop()]),
    "202": lambda: stack.append(str(stack.pop(-2)) * stack.pop()),
    "210": lambda: stack.append(counter),
    "211": lambda: set_counter(stack.pop()),
    "212": lambda: stack.extend(list(str(stack.pop()))),
    "220": flip_ends,
    "221": lambda: stack.append(len(stack[-1])),
    "222": lambda: print(stack[-1]),
    "0000": lambda: stack.reverse(),
    "0001": lambda: stack.sort(),
    "0002": lambda: stack.append(stack[counter]),
    "0010": lambda: stack.append(stack[stack.pop()]),
    "0011": 0,
    "0012": 0,
    "0020": lambda: stack.append(sum(n for n in stack if isinstance(n, numbers.Number))),
    "0021": lambda: stack.append(functools.reduce(lambda x, y: x*y, [n for n in stack if isinstance(n, numbers.Number)], 1)),
    "0022": 0,
    "0100": lambda: (backburner.extend(stack), clear_stack()),
    "0101": lambda: reload_stack(True),
    "0102": lambda: reload_stack(False),
    "0110": lambda: backburner.append(stack.pop()),
    "0111": lambda: backburner.append(list(stack.pop())),
    "0112": lambda: stack.pop().split(stack.pop()),
    "0120": lambda: stack.append(backburner[-1]),
    "0121": lambda: (lambda depth=stack.pop(): (set_stack(stack[-depth:]), backburner.append(stack[:depth])))(),
    "0122": lambda: (lambda depth=stack.pop(): (set_stack(stack[:-depth]), backburner.append(stack[depth:])))(),
    "0200": lambda: set_stack([stack.pop().join(stack)]),
    "0201": lambda: set_stack(["".join(stack)]),
    "0202": lambda: (lambda depth=stack.pop(-2): set_stack(stack[-depth:] + [stack.pop().join(stack[:depth])]))(),
    "0210": lambda: (lambda depth=stack.pop(): set_stack(stack[-depth:] + ["".join(stack[:depth])]))(),
    "0211": 0,
    "0212": 0,
    "0220": lambda: stack.append(stack.pop().split(stack.pop())),
    "0221": lambda: stack.append(stack.pop().split(", ")),
    "0222": 0,
    "1000": lambda: stack.append(is_prime(stack[-1])),
    "1001": lambda: stack.append((lambda s=stack.pop(): s == s[::-1])()),
    "1002": lambda: stack.append(1 / stack.pop()),
    "1010": lambda: stack.append(stack.pop() - 1),
    "1011": lambda: stack.append(stack.pop() + 1),
    "1012": lambda: stack.append(stack.pop() * 2),
    "1020": lambda: stack.append(stack.pop() / 2),
    "1021": lambda: stack.append(stack.pop() ** 2),
    "1022": lambda: float("." + str(stack.pop())),
    "1100": lambda: stack.append(stack.pop() == stack.pop()),
    "1101": lambda: stack.append(stack.pop() != stack.pop()),
    "1102": lambda: stack.append(stack.pop() > stack.pop()),
    "1110": lambda: stack.append(stack.pop() < stack.pop()),
    "1111": lambda: stack.append(stack.pop() >= stack.pop()),
    "1112": lambda: stack.append(stack.pop() <= stack.pop()),
    "1120": lambda: stack.append(stack.pop() in stack),
    "1121": lambda: stack.append(stack.pop() in backburner),
    "1122": lambda: stack.append(stack.pop() == counter),
    "1200": lambda: stack.append(stack.pop() in stack.pop()),
    "1201": lambda: stack.append(stack.pop(-2).find(stack.pop())),
    "1202": 0,
    "1210": 0,
    "1211": 0,
    "1212": lambda: stack.append(stack.pop().lower()),
    "1220": lambda: stack.append(stack.pop().upper()),
    "1221": lambda: stack.append(ord(stack.pop())),
    "1222": lambda: stack.append(chr(stack.pop())),
    "2000": lambda: stack.append(math.floor(stack.pop())),
    "2001": lambda: stack.append(math.ceil(stack.pop())),
    "2002": lambda: stack.append(round(stack.pop())),
    "2010": lambda: stack.append(abs(stack.pop())),
    "2011": 0,
    "2012": 0,
    "2020": lambda: stack.append(len(stack.pop())),
    "2021": 0,
    "2022": 0,
    "2100": lambda: stack.append(min(stack)),
    "2101": lambda: stack.append(max(stack)),
    "2102": lambda: stack.append(stack.count(stack.pop())),
    "2110": lambda: stack.append(sum(stack) / len(stack)),
    "2111": 0,
    "2112": 0,
    "2120": 0,
    "2121": 0,
    "2122": 0,
    "2200": lambda: stack.append(stack.pop(-3).replace(stack.pop(-2), stack.pop())),
    "2201": lambda: stack.append(stack.pop(-3).replace(stack.pop(-2), stack.pop(), 1)),
    "2202": lambda: stack.append(stack.pop(-2).replace(stack.pop(), "")),
    "2210": lambda: stack.append(stack.pop(-2).replace(stack.pop(), "", 1)),
    "2211": 0,
    "2212": lambda: stack.append(eval(stack.pop())),
    "2220": lambda: stack.append(eval(input())),
    "2221": lambda: print(stack[-1]),
    "2222": lambda: error()
}


def run_cmd(name):
    global stack, counter, backburner

    state = {
        "stack": list(stack),
        "counter": counter,
        "backburner": list(backburner)
    }

    # TODO: unknown command

    try:
        commands[name]()
    except IndexError:
        stack = state["stack"]
        counter = state["counter"]
        backburner = state["backburner"]


class AST:
    pass


class Main(AST):
    def __init__(self):
        self.nodes = []


class Do(AST):
    def __init__(self, node):
        self.node = node


class If(AST):
    def __init__(self, first, second):
        self.first = first
        self.second = second


class Literal(AST):
    def __init__(self, val):
        self.val = val


class Command(AST):
    def __init__(self, val):
        self.val = val


class Parser:
    def __init__(self, lexer):
        self.lexer = lexer
        self.token = None

    def parse(self):
        pgm = Main()
        self.token = self.lexer.read()

        while self.token is not None and self.token.type != END and self.token.type != ELSE:
            if self.token.type == DO:
                pgm.nodes.append(Do(self.parse()))

            elif self.token.type == NUMBER or self.token.type == STRING:
                pgm.nodes.append(Literal(self.token.val))

            elif self.token.type == IF:
                first = self.parse()

                if self.token.type == ELSE:
                    second = self.parse()
                else:
                    second = None

                pgm.nodes.append(If(first, second))

            elif self.token.type == COMMAND:
                pgm.nodes.append(Command(self.token.val))

            self.token = self.lexer.read()

        return pgm


class Interpreter:
    def __init__(self, tree):
        self.tree = tree

    def visit(self, node):
        method_name = "visit_" + type(node).__name__
        visitor = getattr(self, method_name.lower())
        return visitor(node)

    def interpret(self):
        self.visit(self.tree)

    def visit_main(self, node):
        for each in node.nodes:
            self.visit(each)

    def visit_do(self, node):
        while counter:
            self.visit(node)

    def visit_if(self, node):
        if stack[-1]:
            self.visit(node.first)
        elif node.second:
            self.visit(node.second)

    def visit_literal(self, node):
        stack.append(node.val)

    def visit_command(self, node):
        run_cmd(node.val)


if source == "":
    with open("info.txt") as f:
        info = f.read()

    print(info)
else:
    main = Parser(Lexer(source)).parse()

    interpreter = Interpreter(main)
    interpreter.interpret()

    try:
        sys.exit(stack[-1])
    except IndexError:
        pass
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.