我在空闲时间使用AdventOfCode.com上发布的编码挑战进行一些编码练习
挑战#6涉及使用一组数百条指令打开和关闭100万(虚拟)灯。我发现自己甚至无法填充一个足够大的ArrayList来处理所有这些"灯"
我决定通过制作1000x1000阵列的1x3阵列开始挑战,这些阵列包含" x-coordinate" " y坐标" "开/关"
我对java效率的经验非常有限(除了常识),我非常欣赏一些方向。
如果您有兴趣,可以采取以下挑战:http://adventofcode.com/day/6
这是我的代码到目前为止,遗憾的是我的craptop(4gb内存)上没有超过索引~7000 - 我在家里确实有一个精美的桌面。
对于如何以更好的内存和速度效率来解决这个问题,我将不胜感激。我是一名学习程序员,我会合理地理解任何指导,无论它是什么。 (学习的链接/位置也受到赞赏)
import java.util.ArrayList;
public class Day6 {
public static void main(String[] args) {
ReadFileClass myReaderClass = new ReadFileClass();
ArrayList<String> allLines = myReaderClass.readFile("/C:/Users/Steven/Desktop/Day6.txt");
ArrayList<ArrayList<Object>> lightArray = new ArrayList<>();
for(int i = 0; i<=999999; i++){
if(i%1000 ==0) System.out.println(i); //To see how fast/far the array populates
int x;
int y;
String status = "off";
for(int j = 0; j<=999; j++){
x = j;
y = i%999;
ArrayList<Object> innerArray = new ArrayList<>();
innerArray.add(x);
innerArray.add(y);
innerArray.add(status);
lightArray.add(innerArray);
}
}
System.out.println(lightArray);
}
}
编辑1 :我不知道ArrayLists究竟发生了什么(垃圾堆积可能?)但我切换到一个字节数组并处理坐标 - &gt;索引转换现在使用方法而且我是一帆风顺。我完成了一个小算法错误后,我会发布我的最终代码(我稍微误解了这个问题)。谢谢你的各种建议!
编辑2 :我的代码现在按预期工作。对于任何有兴趣的人来说,这就是它。)
import java.util.ArrayList;
public class Day6 {
public static void main(String[] args) {
ReadFileExample myReaderClass = new ReadFileExample();
ArrayList<String> allLines = myReaderClass.readFile("/C:/Users/Steven/Desktop/Day6.txt");
byte[] lightArray = new byte[1000000];
for(int i = 0; i<=999999; i++){
lightArray[i] = 0;
}
for(String s : allLines){
int x1, x2, y1, y2;
int indexOfFirstNumber = -1;
String nums = "0123456789";
for(int i = 0; i<s.length();i++){
if(nums.indexOf(s.substring(i,i+1))!=-1){
indexOfFirstNumber = i;
break;
}
}
int IOfirstComma = s.indexOf(",");
int indexOfThrough = s.indexOf("through");
int indexOfX2 = indexOfThrough+8;
int IOsecondComma = s.indexOf(",", IOfirstComma+1);
x1 = Integer.parseInt(s.substring(indexOfFirstNumber, IOfirstComma));
y1 = Integer.parseInt(s.substring(IOfirstComma+1, s.indexOf(" ", IOfirstComma)));
x2 = Integer.parseInt(s.substring(indexOfX2, IOsecondComma));
y2 = Integer.parseInt(s.substring(IOsecondComma+1,s.length()));
ArrayList<Integer> indexesToChange = coordinateRangeToIndexArray(x1, y1, x2, y2);
if(s.substring(0,8).equals("turn off")){
for(int i : indexesToChange){
lightArray[i] = 0;
}
}
else if(s.substring(0,7).equals("turn on")){
for(int i : indexesToChange){
lightArray[i] = 1;
}
}
else if(s.substring(0,6).equals("toggle")){
for(int i : indexesToChange){
if(lightArray[i] == 1){
lightArray[i] = 0;
}
else{
lightArray[i] = 1;
}
}
}
else{
System.out.println("Error: Command not recognized");
}
}
//calculate number of lights that are on
int totalNumLightsOn = 0;
for(int i = 0; i<lightArray.length;i++){
if(lightArray[i] == 1){
totalNumLightsOn++;
}
}
System.out.println(totalNumLightsOn);
}
static ArrayList<Integer> coordinateRangeToIndexArray(int x1, int y1, int x2, int y2){
//Given two coordinates, create an array of all the indexes the smallest possible rectangle encompasses
final int ROW_SIZE = 1000;
ArrayList<Integer> affectedIndexes = new ArrayList<>();
for(int row = x1; row<=x2; row++){
for(int column = y1; column<=y2; column++){
affectedIndexes.add(column*ROW_SIZE+row+1);
}
}
return affectedIndexes;
}
}
答案 0 :(得分:2)
最有效的内存方式是使用yum install freetype-2.4
,在这种情况下,需要1,000,000位(或1兆位)的内存(以及明显的额外几个字节)来存储开/关状态。使用附带的方法可以轻松操作各个位。
祝贺你解决挑战。
答案 1 :(得分:0)
1.000.000每1kb的物体应该需要大约1.000 mb或~1gb。
当我读到你的帖子时,我想
Map <Integer,Lightswitch> = new HashMap <Integer,Lightswitch>();
也许从一个基本的(空的)Lightswitch开始
public class Lightswitch {
}
并将1.000.000的内容添加到地图中。
或(只是想):
byte [] switches = new byte [1000000];
然后字节值代表lightswitch状态(&#39; 0&#39;,&#39; 1&#39;,...)
答案 2 :(得分:0)
只需制作1000X1000的二维整数数组并用0填充它,然后按照说明使用文件处理。例如,将灯光变化0打开为1。