Người chơi tự động BATCH


25

Tôi yêu BATCH, mặc dù thiếu các lệnh chức năng gây sốc, mặc dù thậm chí do không hỗ trợ không nguyên. Tại sao? Bởi vì điều này hoạt động:

SET var=SET
%var% i=0

Điều này sẽ đánh giá để:

SET var=SET
SET i=0

Tuyệt vời phải không? Tôi đã sử dụng kỹ thuật này trong một chương trình BATCH trước đây, vì nó tiết kiệm byte!

Thách thức của bạn, nếu bạn chấp nhận nó, sẽ là "đánh gôn" các chương trình BATCH theo cách này. Bạn phải giảm kích thước byte của chương trình BATCH đầu vào bằng cách bao gồm các SETcâu lệnh sẽ đánh giá thành các phần của chương trình và không có cách nào khác sửa đổi chương trình. (Điều này không cho phép, đổi tên một tên biến thành một tên ngắn hơn. Hãy nhớ rằng BATCH, ngoài các biến, không phân biệt chữ hoa chữ thường.) Điểm của bạn được tính như vậy:

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

Tôi bảo lưu quyền thêm nhiều trường hợp thử nghiệm, để không khuyến khích làm việc để tối ưu hóa chương trình cho các trường hợp thử nghiệm.

Vì lợi ích của thử thách này, bạn SETbáo cáo không thể chứa các ký tự điều khiển ( |, <, >, %) hoặc dấu ngắt hàng. Bạn không được sửa đổi mã ngoài việc di chuyển các đoạn mã bên trong câu lệnh đã đặt. (Nghĩa là, bạn không thể xóa các khoảng trắng không cần thiết, thay thế EQUbằng ==, v.v.) Chúng tôi sẽ giả sử rằng các dòng kết thúc bằng \n.

Các trường hợp thử nghiệm

Mỗi trường hợp thử nghiệm nằm trong một khối mã riêng biệt và mỗi trường hợp thử nghiệm được khép kín, có nghĩa là bạn chỉ nên chơi golf với giả định những gì được đưa ra trong đó. (Tức là, nếu bạn SET d=SETtrong một chương trình, câu lệnh đó sẽ không được tự động đưa ra cho bất kỳ chương trình nào khác). Mỗi kết quả ví dụ có thể được tìm thấy sau mỗi trường hợp thử nghiệm. Có một dòng giữa các trường hợp thử nghiệm.

@ECHO TẮT
Gia tăng SET = 10
: vòng lặp
NẾU% gia tăng% THIẾT BỊ 0 Kết thúc GOTO
ECHO% tăng%
SET / A% tăng% - = 1
Vòng lặp GOTO
:kết thúc
LỐI THOÁT HIỂM

@ECHO TẮT
SET / p INPUT = Nhập đầu vào tại đây:
THIẾT LẬP R =% 1
ECHO char cuối cùng của đầu vào ở đây:% R: ~ -1%

@ECHO TẮT
Gia tăng SET = 10
: e
GOTO
ECHO
: f
GOTO g
ECHO g
: g
GOTO
ECHO
: h
GOTO tôi
ECHO tôi
:tôi
GOTO j
ECHO j
: j
NẾU 3 == 4 (ECHO 4) ELSE (ECHO 5)
NẾU 5 == 3 (GOTO l) ELSE (GOTO k)
: k
ECHO Xong.
ECHO BATCH RA !!
LỐI THOÁT HIỂM
: tôi
GOTO g

ECHO Xin chào, xin chào, xin chào, xin chào, xin chào, xin chào, xin chào!, Xin chào, ello!, Lello.

Kết quả ví dụ:

@ECHO TẮT
Gia tăng SET = 10
: vòng lặp
NẾU% gia tăng% THIẾT BỊ 0 Kết thúc GOTO
ECHO% tăng%
SET / A% tăng% - = 1
Vòng lặp GOTO
:kết thúc
LỐI THOÁT HIỂM
(Đã lưu 0 byte)

@ECHO TẮT
SET% i% = đầu vào tại đây:
THIẾT LẬP / p INPUT = Nhập% i%
THIẾT LẬP R =% 1
ECHO char cuối cùng của% i %% R: ~ -1%
(3 byte đạt được)

@ECHO TẮT
Gia tăng SET = 10
THIẾT LẬP G = GOTO 
THIẾT LẬP e = ECHO 
: e
% g% f
% e% f
: f
% g% g
%ví dụ
: g
% g% h
% e% h
: h
% g% i
% e% i
:tôi
% g% j
% e% j
: j
NẾU 3 == 4 (% e% 4) ELSE (% e% 5)
NẾU 5 == 3 (% g% l) ELSE (% g% k)
: k
% e% Xong.
% e% BATCH RA !!
LỐI THOÁT HIỂM
: tôi
% g% g
(Lưu 10 ký tự)

THIẾT LẬP% h% = ello,
ECHO H% h% H% h% H% h% h% h% h% h% H% h% Xin chào!, H% h% ello!, Lello.
(Đã lưu 1 ký tự)


2
Rút ngắn hàng loạt cho vui và lợi nhuận!
Alex Carlsen

Bạn cần thêm một số thông số kỹ thuật. Tất nhiên AAA %increment%set a=increment¶AAA %%a%%không hợp lệ và AAA %1 BBB %2set a= BBB ¶AAA %1%a%%2là hợp lệ. (iirc) Vì vậy, bạn cần phải chính thức hóa nó. ( đại diện cho một dòng mới)
user202729

Chúng ta có cần xử lý mã đã trì hoãn mở rộng, thoát ký hiệu phần trăm hoặc nhiều dòng cho / if các câu lệnh không? Theo trường hợp thử nghiệm cuối cùng (tạo ra đầu ra bổ sung khi tiếng vang được bật và không có @trước SET) thì đầu ra bên ngoài có thể chấp nhận được từ chương trình đánh gôn không?
urur

1
Tcl tất cả một lần nữa
Ven

1
mặc dù thậm chí là do ?
Adám

Câu trả lời:


4

Chương trình Java 8, Java 10 , 3884 799/795 + đầu ra 484 = tổng số 4368 1283/1279

Có hai hạn chế của mã này:

  • Nó giả định rằng các biến từ A đến Z là miễn phí. (chữ hoa)
  • Nó giả định rằng không có hơn 27 sự thay thế.
  • Ồ, và vì Scanner không hoàn toàn cắt nó, đầu vào trống sẽ bỏ stacktrace.

Nhưng này - có một pro!

  • Đầu ra mã tốt nhất. Luôn luôn.

Mã quản lý để thực hiện tốt hơn các ví dụ được cung cấp bởi tác giả thách thức.

Phiên bản golf này đã được thực hiện bởi 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;}

Hãy thử trực tuyến!

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

Hãy thử trực tuyến! .

Phiên bản gốc

Nó không chơi gôn chút nào, tôi chỉ muốn vui vẻ chứ không phải chịu đựng. Nếu bạn, độc giả thân mến, muốn đánh golf câu trả lời này, xin vui lòng làm điều đó.

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

}

Ví dụ đầu ra:

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

Hãy thử trực tuyến!


Tôi nghĩ tất cả những điều đó "java.util." là lặp đi lặp lại. Bạn có thể muốn đơn giản hóa mã của mình import java.util.*.
A̲̲

Tôi nghĩ jdk nhập khẩu không được tính?
Mark Jeronimus

@A_ bạn có thể sửa đổi câu trả lời của tôi như bạn muốn (trừ khi nó hợp lệ và giữ tinh thần)
Krzysztof Szewchot

1
" Nếu bạn, người đọc thân mến, muốn đánh golf câu trả lời này, vui lòng thực hiện nó. " 799 byte trong Java 8 hoặc 795 byte trong Java 10+ . Không có gì. :) Chắc chắn có thể được đánh gôn thêm, nhưng điều này sẽ làm ngay bây giờ.
Kevin Cruijssen

2
@KevinCruijssen Cảm ơn sự đóng góp. Tôi đã thêm phiên bản của bạn vào bài viết. Hãy thoải mái chỉnh sửa nó mà không hỏi tôi nếu bạn tìm thấy một cái gì đó tốt hơn.
Krzysztof Szewchot
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.