자동 배치 골퍼


25

정수가 아닌 지원이 부족하더라도 충격적인 기능 명령 부족에도 불구하고 BATCH를 좋아합니다. 왜? 이것이 작동하기 때문에 :

SET var=SET
%var% i=0

이것은 다음과 같이 평가됩니다.

SET var=SET
SET i=0

환상적이지 않습니까? 바이트를 저장하기 때문에 BATCH 프로그램 에서이 기술을 사용 했습니다!

당신의 도전은 당신이 그것을 받아 들일 경우 이런 식으로 BATCH 프로그램을 "골프"하는 것입니다. 프로그램의 SET일부로 평가되는 명령문을 포함시켜 입력 BATCH 프로그램의 바이트 크기를 줄이고 다른 방법으로는 프로그램을 수정하지 않아야합니다. 이렇게하면 변수 이름을 더 짧은 이름으로 바꿀 수 없습니다. 변수를 제외하고 BATCH는 대소 문자를 구분하지 않습니다. 점수는 다음과 같이 계산됩니다.

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

본인은 더 많은 테스트 사례를 추가하여 테스트 사례에 맞게 프로그램을 최적화하기위한 작업을 권장하지 않을 권리가 있습니다.

이 도전을 위해, 당신의 SET문은 제어 문자 (포함 할 수 없습니다 |, <, >, %) 또는 줄 바꿈을. set 문 내에서 코드 조각을 이동하는 것 이외의 다른 코드는 수정할 수 없습니다. (즉, 불필요한 공백을 제거하거나로 대체 EQU하는 ==등의 작업을 수행 할 수 없습니다 .) 행이로 끝나는 것으로 가정합니다 \n.

테스트 사례

각 테스트 케이스는 별도의 코드 블록에 있으며, 각 테스트 케이스는 자체 포함되어 있으며, 테스트 케이스에 지정된 내용 만 가정하면 골프를 쳐야합니다. (즉, SET d=SET한 프로그램을 사용하는 경우 해당 설명은 다른 프로그램에 자동으로 제공되지 않습니다). 각 테스트 결과 후에 각 예제 결과를 찾을 수 있습니다. 테스트 사례 사이에는 줄이 있습니다.

@ECHO OFF
SET 증분 = 10
:고리
IF % 증가 % EQU 0 GOTO 종료
에코 % 증가 %
SET / A % 증분 %-= 1
GOTO 루프
:종료
출구

@ECHO OFF
SET / p INPUT = 여기에 입력을 입력하십시오 :
SET R = % 1
ECHO 마지막 입력 문자 : % R : ~ -1 %

@ECHO OFF
SET 증분 = 10
:이자형
고토 f
에코 f
:에프
고토
에코 g
:지
고토
에코
: h
고토 전
에코 i
:나는
고토 j
에코 j
: j
IF 3 == 4 (ECHO 4) ELSE (ECHO 5)
IF 5 == 3 (GOTO l) ELSE (GOTO k)
:케이
에코.
에코 배치 아웃 !!
출구
:엘
고토

ECHO Hello, Hello, Hello, hello, hello, Hello, Hello !, hello, ello !, Lello입니다.

출력 예 :

@ECHO OFF
SET 증분 = 10
:고리
IF % 증가 % EQU 0 GOTO 종료
에코 % 증가 %
SET / A % 증분 %-= 1
GOTO 루프
:종료
출구
(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 = 에코 
:이자형
% g % f
% e % f
:에프
% g % g
% e % g
:지
% g % h
%뭐라고
: h
%미군 병사
% e % i
:나는
% g % j
% e % j
: j
IF 3 == 4 (% e % 4) ELSE (% e % 5)
IF 5 == 3 (% g % l) ELSE (% g % k)
:케이
% e % 완료
% e % 배치 아웃 !!
출구
:엘
% g % g
(10 문자 절약)

SET % h % = 안녕하세요,
ECHO H % h % H % h % H % h % h % h % h % h % H % h % Hello !, 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

확장 가능한 지연, 퍼센트 부호 이스케이프 또는 / if 문에 대해 여러 줄로 된 코드를 처리해야합니까? 마지막 테스트 사례에 따르면 (에코가 켜져 있고 더하기 @전에 추가 출력을 생성하지 않음 SET) 골프 프로그램에서 외부 출력을 허용합니까?
Οurous

1
다시 한번 Tcl
Ven

1
에도 불구하고 ?
Adám

답변:


4

Java 8, Java 10 , 3884 799/795 프로그램 + 484 출력 = 총 4368 1283/1279

이 코드에는 두 가지 제한이 있습니다.

  • A에서 Z까지의 변수가 비어 있다고 가정합니다. (대문자)
  • 대체는 27 개 이하인 것으로 가정합니다.
  • 아, 그리고 스캐너는 그것을 잘 자르지 않기 때문에 빈 입력은 스택 추적을 덤프합니다.

그러나 안녕-프로가있다!

  • 최상의 코드를 출력합니다. 항상.

이 코드는 챌린지 작성자가 제공 한 예제보다 성능이 우수합니다.

이 골프 버전은 Kevin 이 만들었습니다 .

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

온라인으로 사용해보십시오!

자바 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"이라고 생각합니다. 반복적입니다. 코드를로 단순화해야 할 수도 있습니다 import java.util.*.
A̲̲

jdk 가져 오기가 계산되지 않는다고 생각 했습니까?
마크 제로 니 무스

@ A_ 당신이 원하는대로 내 대답을 수정할 수 있습니다 (유효하고 정신을 유지하지 않는 한)
Krzysztof Szewczyk

1
" 독자 여러분,이 답변을 골퍼하고 싶다면, 그렇게하십시오. " Java 8의 경우 799 바이트 또는 Java 10+의 경우 795 바이트 . 천만에요. :) 확실히 더 골프를 칠 수는 있지만 지금은 그렇게 할 것입니다.
케빈 크루이 센

2
@KevinCruijssen 기부 해 주셔서 감사합니다. 게시물에 버전을 추가했습니다. 더 좋은 것을 찾으면 묻지 말고 자유롭게 편집하십시오.
Krzysztof Szewczyk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.