Pegolf BATCH otomatis

25

Saya suka BATCH, meskipun tidak ada perintah fungsional yang mengejutkan, meskipun karena kurangnya dukungan non-integer. Mengapa? Karena ini berfungsi:

SET var=SET
%var% i=0

Ini akan mengevaluasi untuk:

SET var=SET
SET i=0

Fantastis, bukan? Saya telah menggunakan teknik ini dalam program BATCH sebelumnya, karena menghemat byte!

Tantangan Anda, seandainya Anda menerimanya, adalah melakukan "golf" program BATCH dengan cara ini. Anda harus mengurangi ukuran byte dari program BATCH input dengan memasukkan SETpernyataan yang akan mengevaluasi bagian-bagian dari program, dan tidak ada cara lain memodifikasi program. (Ini melarang, misalnya, mengganti nama nama variabel menjadi sesuatu yang lebih pendek. Ingatlah bahwa BATCH, selain dari variabel, tidak peka huruf besar-kecil.) Skor Anda dihitung sebagai berikut:

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

Saya berhak untuk menambahkan lebih banyak test case, sehingga mencegah bekerja untuk mengoptimalkan program untuk case test.

Demi tantangan ini, Anda SETpernyataan tidak dapat berisi karakter kontrol ( |, <, >, %) atau linebreaks. Anda tidak boleh memodifikasi kode selain untuk memindahkan potongan kode di dalam pernyataan yang ditetapkan. (Yaitu, Anda tidak boleh menghapus spasi kosong yang tidak perlu, ganti EQUdengan ==, dll.) Kami akan menganggap bahwa garis diakhiri dengan \n.

Uji kasus

Setiap test case berada dalam blok kode yang terpisah, dan setiap case test mandiri, artinya Anda harus bermain golf hanya dengan asumsi apa yang diberikan di dalamnya. (Yaitu, jika Anda SET d=SETdalam satu program, pernyataan itu tidak akan secara otomatis diberikan ke program lain). Setiap contoh hasil dapat ditemukan setelah setiap test case. Ada garis antara kasus uji.

@ECHO MATI
SET kenaikan = 10
: loop
JIKA% bertambah% EQU 0 GOTO akhir
ECHO% kenaikan%
SET / A% kenaikan% - = 1
GOTO loop
:akhir
KELUAR

@ECHO MATI
SET / p INPUT = Masukkan input di sini:
SET R =% 1
Masukan terakhir dari ECHO:% R: ~ -1%

@ECHO MATI
SET kenaikan = 10
: e
GOTO f
ECHO f
: f
GOTO g
ECHO g
: g
GOTO h
ECHO h
: h
GOTO i
ECHO saya
:saya
GOTO j
ECHO j
: j
JIKA 3 == 4 (ECHO 4) ELSE (ECHO 5)
JIKA 5 == 3 (GOTO l) ELSE (GOTO k)
: k
ECHO Selesai.
ECHO BATCH OUT !!
KELUAR
: l
GOTO g

ECHO Halo, Halo, Halo, Halo, Halo, Halo, Halo !, Halo, Ello !, Lello.

Output contoh:

@ECHO MATI
SET kenaikan = 10
: loop
JIKA% bertambah% EQU 0 GOTO akhir
ECHO% kenaikan%
SET / A% kenaikan% - = 1
GOTO loop
:akhir
KELUAR
(0 byte disimpan)

@ECHO MATI
SET% i% = masukan di sini:
SET / p INPUT = Masukkan% i%
SET R =% 1
ECHO Karakter terakhir dari% i %% R: ~ -1%
(3 byte diperoleh)

@ECHO MATI
SET kenaikan = 10
SET g = GOTO 
SET e = ECHO 
: e
% g% f
% e% f
: f
% g% g
%misalnya
: g
% g% h
% e% h
: h
% g% i
% e% i
:saya
% g% j
% e% j
: j
JIKA 3 == 4 (% e% 4) ELSE (% e% 5)
JIKA 5 == 3 (% g% l) ELSE (% g% k)
: k
% e% Selesai.
% e% BATCH OUT !!
KELUAR
: l
% g% g
(10 karakter tersimpan)

SET% h% = ello,
ECHO H% h% H% h% H% h% h% h% h% h% H% h% Halo !, h% h% ello !, Lello.
(1 karakter disimpan)

Conor O'Brien
sumber
2
Shortening batch untuk kesenangan dan keuntungan!
Alex Carlsen
Anda memerlukan lebih banyak spesifikasi. Tentu saja AAA %increment%set a=increment¶AAA %%a%%tidak valid, dan AAA %1 BBB %2set a= BBB ¶AAA %1%a%%2valid. (iirc) Jadi Anda perlu memformalkannya. ( mewakili baris baru)
user202729
Apakah kita perlu menangani kode yang menunda ekspansi yang diaktifkan, persen-keluar, atau multi-line untuk / jika pernyataan? Sebagai per kasus uji terakhir (yang menghasilkan output tambahan saat gema aktif dan tidak ada @sebelum SET) apakah output asing dapat diterima dari program golf?
Surous
1
Tcl lagi
Ven
1
meskipun karena ?
Adám

Jawaban:

4

Java 8, Java 10 , 3884 799/795 program + 484 output = 4368 1283/1279 total

Ada dua batasan kode ini:

  • Diasumsikan bahwa variabel dari A hingga Z gratis. (huruf besar)
  • Diasumsikan bahwa tidak ada lebih dari 27 pergantian.
  • Oh, dan karena Pemindai tidak cukup memotongnya, input kosong membuang stacktrace.

Tapi hei - ada pro!

  • Menghasilkan kode terbaik. Selalu.

Kode ini berfungsi lebih baik daripada contoh yang diberikan oleh penulis tantangan.

Versi golf ini dibuat oleh Kevin .

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;}

Cobalah online!

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;}

Cobalah online! .

Versi asli

Ini sama sekali bukan golf, saya hanya ingin bersenang-senang, bukan untuk menderita. Jika Anda, pembaca yang budiman, ingin memberikan jawaban ini, silakan lakukan.

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);
		
		
	}

}

Contoh output:

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

Cobalah online!

Krzysztof Szewczyk
sumber
Saya pikir semua itu "java.util." berulang-ulang. Anda mungkin ingin menyederhanakan kode Anda import java.util.*.
A
Saya pikir impor jdk tidak masuk hitungan?
Mark Jeronimus
@A_ Anda dapat mengubah jawaban saya seperti yang Anda inginkan (kecuali jika itu valid dan tetap semangat)
Krzysztof Szewczyk
1
" Jika Anda, pembaca yang budiman, ingin menuliskan jawaban ini, silakan lakukan. " 799 byte di Java 8 atau 795 byte di Java 10+ . Sama-sama. :) Pasti bisa bermain golf lagi, tetapi ini akan berlaku untuk saat ini.
Kevin Cruijssen
2
@KevinCruijssen Terima kasih atas kontribusinya. Saya telah menambahkan versi Anda ke pos. Jangan ragu untuk mengeditnya tanpa bertanya kepada saya apakah Anda menemukan sesuatu yang lebih baik.
Krzysztof Szewczyk