You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							106 lines
						
					
					
						
							2.3 KiB
						
					
					
				
			
		
		
	
	
							106 lines
						
					
					
						
							2.3 KiB
						
					
					
				#!/usr/bin/env julia
 | 
						|
 | 
						|
using Test
 | 
						|
 | 
						|
mutable struct Dir
 | 
						|
  path :: String
 | 
						|
  dnames :: Vector{String}
 | 
						|
  fsize :: Int32
 | 
						|
end
 | 
						|
 | 
						|
function get_dir_map(infile)
 | 
						|
  cwd = Vector{String}()
 | 
						|
  path = "/"
 | 
						|
  dirmap = Dict{String, Dir}()
 | 
						|
  open(infile, "r") do io
 | 
						|
    for line in eachline(io)
 | 
						|
      parts = split(line)
 | 
						|
      if parts[1] == "\$"
 | 
						|
        if parts[2] == "cd"
 | 
						|
          if parts[3] == "/"
 | 
						|
            empty!(cwd)
 | 
						|
          elseif parts[3] == ".."
 | 
						|
            pop!(cwd)
 | 
						|
          else
 | 
						|
            push!(cwd, parts[3])
 | 
						|
          end
 | 
						|
          path = "/" * join(cwd, '/')
 | 
						|
          if ! haskey(dirmap, path)
 | 
						|
            dirmap[path] = Dir(path, [], 0)
 | 
						|
          end
 | 
						|
        elseif parts[2] != "ls"
 | 
						|
          println("Unknown command: ", line)
 | 
						|
        end
 | 
						|
      else
 | 
						|
        parts = split(line, limit=2)
 | 
						|
        if parts[1] == "dir"
 | 
						|
          push!(dirmap[path].dnames, joinpath(path, parts[2]))
 | 
						|
        else
 | 
						|
          dirmap[path].fsize += parse(Int, parts[1])
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  for k in sort(collect(keys(dirmap)), by=p->length(p), rev=true)
 | 
						|
    v = dirmap[k]
 | 
						|
    for p in v.dnames
 | 
						|
      dirmap[k].fsize += dirmap[p].fsize
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return dirmap
 | 
						|
end
 | 
						|
  
 | 
						|
 | 
						|
function small_dir_sum(infile)
 | 
						|
  dirmap = get_dir_map(infile)
 | 
						|
  small_sum = 0
 | 
						|
  for v in values(dirmap)
 | 
						|
    if v.fsize <= 100000
 | 
						|
      small_sum += v.fsize
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return small_sum
 | 
						|
end
 | 
						|
 | 
						|
function delete_candidate_size(infile)
 | 
						|
  dirmap = get_dir_map(infile)
 | 
						|
  total = 70000000
 | 
						|
  want = 30000000
 | 
						|
  used = dirmap["/"].fsize
 | 
						|
  free = total - used
 | 
						|
  need = want - free
 | 
						|
  candidates = Vector{Int64}()
 | 
						|
  # println("used ", used)
 | 
						|
  # println("free ", free)
 | 
						|
  # println("need ", need)
 | 
						|
  for v in values(dirmap)
 | 
						|
    if v.fsize >= need
 | 
						|
      push!(candidates, v.fsize)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return minimum(candidates)
 | 
						|
end
 | 
						|
 | 
						|
function test()
 | 
						|
  @testset "disk usage small dir sum" verbose=true begin
 | 
						|
    @test small_dir_sum("example.txt") == 95437
 | 
						|
    @test small_dir_sum("input.txt") == 1306611
 | 
						|
  end
 | 
						|
  @testset "disk usage delete candidate size" verbose=true begin
 | 
						|
    @test delete_candidate_size("example.txt") == 24933642
 | 
						|
    @test delete_candidate_size("input.txt") == 13210366
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
function main()
 | 
						|
  if size(ARGS, 1) == 0
 | 
						|
    test()
 | 
						|
  else
 | 
						|
    infile = ARGS[1]
 | 
						|
    println("infile = ", infile)
 | 
						|
    println("error priority sum: ", rucksack_errors(infile))
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
main()
 |