นักกอล์ฟแบทช์อัตโนมัติ


25

ฉันรัก BATCH แม้จะไม่มีคำสั่งที่ใช้งานได้อย่างน่าตกใจแม้ว่าจะเป็นเพราะขาดการสนับสนุนที่ไม่ใช่จำนวนเต็มก็ตาม ทำไม? เพราะสิ่งนี้ได้ผล:

SET var=SET
%var% i=0

สิ่งนี้จะประเมินว่า:

SET var=SET
SET i=0

เยี่ยมเลยใช่มั้ย ฉันเคยใช้เทคนิคนี้ในโปรแกรม BATCHมาก่อนเพราะมันช่วยประหยัดไบต์!

ความท้าทายของคุณคุณควรยอมรับมันคือโปรแกรม "กอล์ฟ" BATCH ด้วยวิธีนี้ คุณจะต้องลดขนาดไบต์ของโปรแกรม BATCH อินพุตโดยการรวมSETคำสั่งที่จะประเมินเป็นส่วนของโปรแกรมและไม่มีทางแก้ไขโปรแกรม (สิ่งนี้ไม่อนุญาตให้พูดการเปลี่ยนชื่อตัวแปรเป็นชื่อที่สั้นกว่าโปรดจำไว้ว่า BATCH นอกเหนือจากตัวแปรนั้นไม่คำนึงถึงขนาดตัวพิมพ์) คะแนนของคุณจะถูกคำนวณดังนี้:

score = # of characters in your program + 5*(net result bytes in test cases below)

ฉันขอสงวนสิทธิ์ในการเพิ่มกรณีทดสอบเพิ่มเติมเพื่อขัดขวางการทำงานเพื่อเพิ่มประสิทธิภาพโปรแกรมสำหรับกรณีทดสอบ

เพื่อประโยชน์ของความท้าทายนี้, คุณSETงบไม่สามารถมีตัวควบคุม ( |, <, >, %) หรือขึ้นบรรทัดใหม่ คุณไม่สามารถแก้ไขรหัสอื่นนอกเหนือจากการย้ายชิ้นส่วนของรหัสภายในชุดคำสั่ง (นั่นคือคุณไม่อาจลบช่องว่างที่ไม่จำเป็นแทนที่EQUด้วย==ฯลฯ ) \nเราจะสมมติว่าเส้นที่จบลงด้วยการ

กรณีทดสอบ

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

@ECHO OFF
การเพิ่ม SET = 10
: ห่วง
IF% เพิ่มขึ้น% EQU 0 GOTO จบ
ECHO% เพิ่มขึ้น%
SET / A% เพิ่มขึ้น% - = 1
GOTO ลูป
: ปลาย
EXIT

@ECHO OFF
ชุด / p อินพุต = ป้อนอินพุตที่นี่:
SET R =% 1
ECHO อักขระตัวสุดท้ายของอินพุตที่นี่:% R: ~ -1%

@ECHO OFF
การเพิ่ม SET = 10
: อี
GOTO f
ECHO f
: F
GOTO กรัม
ECHO กรัม
: กรัม
GOTO ชั่วโมง
ECHO ชั่วโมง
: เอช
GOTO i
ECHO i
:ผม
GOTO j
ECHO j
: J
หาก 3 == 4 (ECHO 4) อื่น ๆ (ECHO 5)
ถ้า 5 == 3 (GOTO l) อื่น ๆ (GOTO k)
: k
ECHO เสร็จแล้ว
ECHO BATCH OUT !!
EXIT
: L
GOTO กรัม

ECHO สวัสดี, สวัสดี, สวัสดี, สวัสดี, สวัสดี, สวัสดี, Hello!, hello, ello !, Lello

ตัวอย่างผลลัพธ์:

@ECHO OFF
การเพิ่ม SET = 10
: ห่วง
IF% เพิ่มขึ้น% EQU 0 GOTO จบ
ECHO% เพิ่มขึ้น%
SET / A% เพิ่มขึ้น% - = 1
GOTO ลูป
: ปลาย
EXIT
(บันทึก 0 ไบต์)

@ECHO OFF
SET% i% = อินพุตที่นี่:
SET / p INPUT = ป้อน% i%
SET R =% 1
ECHO อักขระสุดท้ายของ% i %% R: ~ -1%
(ได้รับ 3 ไบต์)

@ECHO OFF
การเพิ่ม SET = 10
ชุด g = GOTO 
SET e = ECHO 
: อี
% g f%
E% f%
: F
% g% g
%เช่น
: กรัม
% g% h
E%% h
: เอช
% g% ฉัน
E%% ฉัน
:ผม
% g j%
E% j%
: J
หาก 3 == 4 (% e% 4) อื่น ๆ (% e% 5)
หาก 5 == 3 (% g% l) ELSE (% g% k)
: k
E%% เสร็จสิ้น
% e% BATCH OUT !!
EXIT
: L
% g% g
(บันทึก 10 ตัวอักษร)

SET% h% = ello
ECHO H% h% H% h% H% h% h% h% h% h% h% h% h% สวัสดี!! h% h% ello !, Lello
(บันทึก 1 ตัวอักษร)


2
การย่อชุดเพื่อความสนุกสนานและผลกำไร!
Alex Carlsen

คุณต้องการข้อมูลจำเพาะเพิ่มเติม แน่นอนAAA %increment%set a=increment¶AAA %%a%%ไม่ถูกต้องและAAA %1 BBB %2set a= BBB ¶AAA %1%a%%2ถูกต้อง (iirc) ดังนั้นคุณต้องทำมันให้เป็นระเบียบ ( หมายถึงการขึ้นบรรทัดใหม่)
user202729

เราจำเป็นต้องจัดการกับรหัสที่เปิดใช้งานการขยายล่าช้าเครื่องหมายเปอร์เซ็นต์หรือหลายบรรทัดสำหรับ / ถ้าคำสั่งหรือไม่ ตามกรณีการทดสอบครั้งล่าสุด (ซึ่งสร้างเอาต์พุตเพิ่มเติมเมื่อ echo เปิดอยู่และไม่เคยมี@มาก่อนSET) เป็นเอาต์พุตภายนอกที่ยอมรับได้จากโปรแกรมกอล์ฟ?
Οurous

1
Tcl อีกครั้ง
Ven

1
แม้จะมีแม้กระทั่งเนื่องจาก ?
อดัม

คำตอบ:


4

Java 8, Java 10 , 3884 799/795 โปรแกรม + เอาต์พุต 484 = รวม4368 1283/1279

รหัสนี้มีข้อ จำกัด สองประการ:

  • มันถือว่าตัวแปรจาก A ถึง Z นั้นว่าง (ตัวพิมพ์ใหญ่)
  • สันนิษฐานว่าไม่มีการแทนที่มากกว่า 27 ครั้ง
  • โอ้และเนื่องจากเครื่องสแกนเนอร์ไม่ได้ตัดมันอินพุตว่างจึงทิ้งสแต็คเทรซ

แต่เฮ้ - มีมืออาชีพ!

  • เอาท์พุตรหัสที่ดีที่สุด เสมอ.

รหัสนี้สามารถทำงานได้ดีกว่าตัวอย่างที่ผู้เขียนท้า

รุ่นนี้แข็งแรงเล่นกอล์ฟได้รับการทำโดยเควิน

Java 8

c->{List<String>S=new Stack();HashMap<String,Integer>h=new HashMap(),s=new HashMap();int v=65,l=c.length(),b,e;do{for(b=0,l=c.length(),s.clear();b!=l;b++)for(e=b;++e<=l;)S.add(c.substring(b,e));S.removeIf(t->t.length()<5|t.matches(".*[\n|<%>].*"));S.forEach(t->h.merge(t,1,Integer::sum));S.clear();h.entrySet().removeIf(t->t.getValue()==1);String Y=c;int L=l;char V=(char)v;h.forEach((k,x)->{String i=Y,t;for(int j,I,q;i.contains(k);i=t+"%"+V+"%"+i.substring(j+k.length(),i.length())){for(I=-1,t=i.substring(q=0,j=i.indexOf(k));(I=t.indexOf("%",++I))>=0;q++);if(q%2>0)return;}i="SET "+V+"="+k+"\n"+i;if(i.length()<L)s.put(i,L-i.length());});h.clear();v++;c=s.isEmpty()?c:s.entrySet().stream().max((x,y)->x.getValue()>y.getValue()?1:-1).get().getKey();}while(l>c.length());return c;}

ลองออนไลน์!

Java 10

c->{var S=new Stack<String>();HashMap<String,Integer>h=new HashMap(),s=new HashMap();int v=65,l=c.length(),b,e;do{for(b=0,l=c.length(),s.clear();b!=l;b++)for(e=b;++e<=l;)S.add(c.substring(b,e));S.removeIf(t->t.length()<5|t.matches(".*[\n|<%>].*"));S.forEach(t->h.merge(t,1,(x,y)->x+y));S.clear();h.entrySet().removeIf(t->t.getValue()==1);var Y=c;int L=l;var V=(char)v;h.forEach((k,x)->{String i=Y,t;for(int j,I,q;i.contains(k);i=t+"%"+V+"%"+i.substring(j+k.length(),i.length())){for(I=-1,t=i.substring(q=0,j=i.indexOf(k));(I=t.indexOf("%",++I))>=0;q++);if(q%2>0)return;}i="SET "+V+"="+k+"\n"+i;if(i.length()<L)s.put(i,L-i.length());});h.clear();v++;c=s.isEmpty()?c:s.entrySet().stream().max((x,y)->x.getValue()>y.getValue()?1:-1).get().getKey();}while(l>c.length());return c;}

ลองออนไลน์! .

รุ่นเดิม

มันไม่ได้เล่นกอล์ฟเลยฉันแค่อยากสนุกและไม่ต้องทนทุกข์ หากคุณผู้อ่านที่รักอยากจะเล่นกอล์ฟคำตอบนี้โปรดทำมัน

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class Main {
	List<String> substrings = new ArrayList<String>();
	HashMap<String, Integer> hm = new HashMap<String, Integer>();
	HashMap<String, Integer> scores = new HashMap<String, Integer>();
	
	private int v1 = 65;
	
	public static String rfos(String inputString, String stringToReplace,
	        String stringToReplaceWith) {

	    int length = stringToReplace.length();
	    int inputLength = inputString.length();

	    int startingIndexofTheStringToReplace = inputString.indexOf(stringToReplace);

	    if(count(inputString.substring(0, startingIndexofTheStringToReplace), "%") % 2 == 1)
	    	return null;
	    
	    String finalString = inputString.substring(0, startingIndexofTheStringToReplace) + stringToReplaceWith
	            + inputString.substring(startingIndexofTheStringToReplace + length, inputLength);

	    return finalString;

	}
	
	public static int count(String text, String find) {
        int index = 0, count = 0, length = find.length();
        while( (index = text.indexOf(find, index)) != -1 ) {                
                index += length; count++;
        }
        return count;
	}
	
	private String process(String program) {
		int begin = 0, end, il = program.length();
		
		scores.clear();
		
		while(begin != program.length()) {
			for(end = begin + 1; end < program.length() + 1; end++)
				substrings.add(program.substring(begin, end));
			begin++;
		}
		
		substrings.removeIf(new Predicate<String>() {
			@Override
			public boolean test(String arg0) {
				return arg0.length() <= 4 || arg0.contains("\n")
						|| arg0.contains("|")
						|| arg0.contains("<")
						|| arg0.contains("%")
						|| arg0.contains(">");
			}
		});
		
		substrings.forEach(new Consumer<String>() {

			@Override
			public void accept(String t) {
				if(hm.containsKey(t)) {
					hm.replace(t, hm.get(t) + 1);
				} else {
					hm.put(t, 1);
				}
			}
			
		});
		
		substrings.clear();
		
		hm.entrySet().removeIf(new Predicate<Map.Entry<String, Integer>>() {

			@Override
			public boolean test(Map.Entry<String, Integer> t) {
				return t.getValue() == 1;
			}
			
		});
		
		hm.forEach(new BiConsumer<String, Integer>() {
			
			@Override
			public void accept(String arg0, Integer arg1) {
				String iteration = program;
				boolean between = false;
				while(iteration.contains(arg0)) {
					iteration = rfos(iteration, arg0, "%" + Character.toString((char) v1) + "%");
					if(iteration == null)
						return;
				}
				iteration = "SET " + Character.toString((char) v1) + "=" + arg0 + "\n" + iteration;
				if(iteration.length() < program.length())
					scores.put(iteration, program.length() - iteration.length());
			}
			
		});
		
		hm.clear();
		v1++;
		
		if(scores.isEmpty())
			return program;
		else
			return scores.entrySet().stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();
	}

	public static void main(String[] args) {
		Main processor = new Main();
		int genid = 0, before = 0, after = 0;
		String currentCode = new Scanner(System.in).useDelimiter("\\Z").next();
		
		System.out.println("Calculating first generation...");
		
		do {
			String cc = processor.process(currentCode);
			before = currentCode.length();
			after = cc.length();
			
			currentCode = cc;
			
			if(before > after) {
				System.out.println("Generation " + genid++);
				System.out.println(before + " -> " + after);
				System.out.println("***\n" + cc + "\n***");
			} else {
				System.out.println("Generation FAIL " + genid++);
				System.out.println(before + " -> " + after);
				System.out.println("***\n" + cc + "\n***");
			}
		} while(before > after);
		
		
	}

}

ตัวอย่างผลลัพธ์:

SET B=GOTO 
SET A=ECHO 
@%A%OFF
SET increment=10
:e
%B%f
%A%f
:f
%B%g
%A%g
:g
%B%h
%A%h
:h
%B%i
%A%i
:i
%B%j
%A%j
:j
IF 3==4 ( %A%4 ) ELSE ( %A%5 )
IF 5==3 ( %B%l ) ELSE ( %B%k )
:k
%A%Done.
%A%BATCH OUT!!
EXIT
:l
%B%g

ลองออนไลน์!


ฉันคิดว่า "java.util" ซ้ำ ๆ คุณอาจจะ Wany import java.util.*เพื่อลดความซับซ้อนรหัสของคุณ
A

ฉันคิดว่าการนำเข้า jdk ไม่นับ?
Mark Jeronimus

@A_ คุณสามารถแก้ไขคำตอบของฉันได้ตามที่คุณต้องการ (เว้นแต่ว่ามันจะถูกต้องและรักษาวิญญาณ)
Krzysztof Szewczyk

1
" หากคุณผู้อ่านที่รักขอกอล์ฟคำตอบนี้โปรดทำมัน. " 799 ไบต์ในชวา 8หรือ795 ไบต์ในชวา 10+ ไม่เป็นไร :) สามารถตีกอล์ฟได้มากกว่านี้ แต่ตอนนี้จะทำ
Kevin Cruijssen

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