Golfista Auto BATCH

25

Uwielbiam BATCH, pomimo szokującego braku komend funkcjonalnych, nawet ze względu na brak obsługi liczb całkowitych. Czemu? Ponieważ to działa:

SET var=SET
%var% i=0

Oznaczałoby to:

SET var=SET
SET i=0

Fantastycznie, prawda? Wcześniej stosowałem tę technikę w programie BATCH , ponieważ oszczędza ona bajty!

Twoim wyzwaniem, jeśli je zaakceptujesz, będzie zagranie w ten sposób w programy BATCH „golf”. Masz zmniejszyć rozmiar bajtu wejściowego programu BATCH, włączając SETinstrukcje, które będą oceniać na części programu, i w żaden inny sposób nie modyfikują programu. (To wyklucza, powiedzmy, zmianę nazwy zmiennej na coś krótszego. Pamiętaj, że BATCH, oprócz zmiennych, nie uwzględnia wielkości liter.) Twój wynik jest obliczany w następujący sposób:

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

Zastrzegam sobie prawo do dodawania kolejnych przypadków testowych, aby zniechęcić do pracy nad optymalizacją programu dla przypadków testowych.

Przez wzgląd na to wyzwanie, Twoje SETwypowiedzi nie może zawierać znaków sterujących ( |, <, >, %) lub linebreaks. Nie możesz modyfikować kodu poza przenoszeniem fragmentów kodu w instrukcji set. (To znaczy, że nie może usunąć niepotrzebne spacje, należy wymienić EQUz ==, itd.) Zakładamy, że linie kończą \n.

Przypadki testowe

Każdy przypadek testowy znajduje się w osobnym bloku kodu, a każdy przypadek testowy jest samodzielny, co oznacza, że ​​powinieneś grać w golfa, zakładając, co jest w nim zawarte. (Tj. Jeśli jesteś SET d=SETw jednym programie, to oświadczenie nie zostanie automatycznie przekazane żadnemu innemu programowi). Każdy przykładowy wynik można znaleźć po każdym przypadku testowym. Między przypadkami testowymi istnieje granica.

@ECHO OFF
Krok przyrostu = 10
:pętla
JEŚLI% przyrost% EQU 0 GOTO koniec
ECHO% przyrost%
SET / A% przyrost% - = 1
Pętla GOTO
:koniec
WYJŚCIE

@ECHO OFF
SET / p INPUT = Tutaj wprowadź dane wejściowe:
SET R =% 1
ECHO Ostatni znak wprowadzania tutaj:% R: ~ -1%

@ECHO OFF
Krok przyrostu = 10
:mi
GOTO f
ECHO f
:fa
GOTO g
ECHO g
:sol
GOTO godz
ECHO godz
: h
GOTO i
ECHO i
:ja
GOTO j
ECHO j
:jot
JEŻELI 3 == 4 (ECHO 4) ELSE (ECHO 5)
JEŻELI 5 == 3 (GOTO l) ELSE (GOTO k)
: k
ECHO Gotowe.
ECHO BATCH OUT !!
WYJŚCIE
: l
GOTO g

ECHO Cześć, cześć, cześć, cześć, cześć, cześć, cześć !, cześć, ello !, Lello.

Przykładowe wyniki:

@ECHO OFF
Krok przyrostu = 10
:pętla
JEŚLI% przyrost% EQU 0 GOTO koniec
ECHO% przyrost%
SET / A% przyrost% - = 1
Pętla GOTO
:koniec
WYJŚCIE
(0 bajtów zapisanych)

@ECHO OFF
SET% i% = wprowadź tutaj:
SET / p INPUT = Wpisz% i%
SET R =% 1
ECHO Ostatni znak% i %% R: ~ -1%
(3 zdobyte bajty)

@ECHO OFF
Krok przyrostu = 10
ZESTAW g = GOTO 
SET e = ECHO 
:mi
% g% f
% e% f
:fa
% g% g
%na przykład
:sol
% g% h
% e% h
: h
%żołnierz amerykański
% e% i
:ja
% g% j
% e% j
:jot
JEŻELI 3 == 4 (% e% 4) ELSE (% e% 5)
JEŻELI 5 == 3 (% g% l) ELSE (% g% k)
: k
% e% Gotowe.
% e% WYPALENIE !!
WYJŚCIE
: l
% g% g
(10 znaków zapisanych)

ZESTAW% h% = ello,
ECHO H% h% H% h% H% h% h% h% h% h% H% h% Witaj !, h% h% ello !, Lello.
(1 znak zapisany)

Conor O'Brien
źródło
2
Skracanie partii dla zabawy i zysku!
Alex Carlsen
Potrzebujesz więcej specyfikacji. Oczywiście AAA %increment%set a=increment¶AAA %%a%%jest nieprawidłowy, a AAA %1 BBB %2set a= BBB ¶AAA %1%a%%2jest ważny. (iirc) Więc musisz to sformalizować. ( reprezentuje nowy wiersz)
user202729
Czy musimy obsługiwać kod, który ma włączone opóźnione rozwijanie, zmiany znaczenia znaku procentu lub wieloliniowe instrukcje for / if? Jak w ostatnim przypadku testowym (który generuje dodatkowe wyjście, gdy echo jest włączone i nie ma @przed nim SET), czy obce wyjście jest dopuszczalne z programu golfowego?
Οurous
1
Tcl od nowa
Ven
1
mimo że nawet z powodu ?
Adám

Odpowiedzi:

4

Java 8, Java 10 , 3884 799/795 program + 484 wyjście = 4368 1283/1279 łącznie

Istnieją dwa ograniczenia tego kodu:

  • Zakłada, że ​​zmienne od A do Z są dowolne. (duże litery)
  • Zakłada się, że nie ma więcej niż 27 zmian.
  • Aha, a ponieważ Scanner nie całkiem go wycina, puste dane wejściowe zrzucają ślad stosu.

Ale hej - jest profesjonalista!

  • Wysyła najlepszy kod. Zawsze.

Kod działa lepiej niż przykłady podane przez autora wyzwania.

Ta wersja gry w golfa została wykonana przez Kevina .

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

Wypróbuj 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;}

Wypróbuj online! .

Orginalna wersja

To wcale nie jest gra w golfa, chciałem po prostu dobrze się bawić, nie cierpieć. Jeśli, drogi czytelniku, chciałbyś zagrać w golfa w tej odpowiedzi, zrób to.

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

}

Przykładowe dane wyjściowe:

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

Wypróbuj online!

Krzysztof Szewczyk
źródło
Myślę, że całe to „java.util”. jest powtarzalny. Możesz uprościć swój kod import java.util.*.
Myślałem, że import jdk się nie liczy?
Mark Jeronimus
@A_ możesz zmodyfikować moją odpowiedź, jeśli chcesz (chyba że jest poprawna i zachowuje ducha)
Krzysztof Szewczyk
1
Jeśli, drogi czytelniku, chciałbyś zagrać w golfa w tej odpowiedzi, zrób to.799 bajtów w Javie 8 lub 795 bajtów w Javie 10+ . Nie ma za co. :) Zdecydowanie można jeszcze zagrać w golfa, ale na razie to wystarczy.
Kevin Cruijssen
2
@KevinCruijssen Dzięki za wkład. Dodałem twoją wersję do postu. Możesz go edytować bez pytania, czy znajdziesz coś lepszego.
Krzysztof Szewczyk