Compare commits

..

No commits in common. "19adece4a2c14751806bfd662c9a4ad79e23c54a" and "f03131610f701f84723b9e06cfb80176b747ce7d" have entirely different histories.

3 changed files with 30 additions and 28 deletions

View file

@ -3,39 +3,46 @@ def String.words (s : String) :=
def String.lines (s : String) := def String.lines (s : String) :=
s.splitOn "\n" |>.filter (¬·.isEmpty) |>.toArray s.splitOn "\n" |>.filter (¬·.isEmpty) |>.toArray
def Array.unlines (xs : Array String) : String := -- TODO: remove trailing
xs.foldl (· ++ · ++ "\n") "" def Array.unlines (xs : Array String) : String := Id.run do
let mut out := ""
for line in xs do
out := out ++ line ++ "\n"
return out
def String.replicate : Nat → Char → String def String.replicate : Nat → Char → String
| 0, _ => "" | 0, _ => ""
| n+1, x => replicate n x |>.push x | n+1, x => replicate n x |>.push x
def sep (xs : Array String) (space : Fin (xs.size-1) → String) def sep (xs space : Array String)
: String := Id.run do : String := Id.run do
let mut out := "" let mut out := ""
let mut i := 0 let mut i := 0
while h : i < xs.size do while h : i < xs.size do
out := out ++ xs[i] out := out ++ xs[i]
if h : i < xs.size - 1 then if let some space := space[i]?
out := out ++ space ⟨i, h⟩ then out := out ++ space
i := i + 1 i := i + 1
return out return out
def justify (width : Nat) (words : Array String) : String := def justify : Nat → Array String → String
sep words space | _, #[word] => word
where | width, words =>
space i := if i.val ≤ largeSpaces then largeSpace else smallSpace let wordsLength := words.foldr (·.length + ·) 0
largeSpace := smallSpace.push ' ' let spacesNeeded := width - wordsLength
smallSpace := String.replicate smallSpaceLen ' ' let numSpaces := words.size - 1
smallSpaceLen := spacesNeeded / numSpaces let smallSpaceLen := spacesNeeded / numSpaces
largeSpaces := spacesNeeded % numSpaces let smallSpace := String.replicate smallSpaceLen ' '
numSpaces := words.size - 1 let largeSpaces := spacesNeeded % numSpaces
spacesNeeded := width - wordsLength let smallSpaces := numSpaces - largeSpaces
wordsLength := words.foldr (·.length + ·) 0 let largeSpace := smallSpace.push ' '
let spaces := Array.mkArray largeSpaces largeSpace
++ Array.mkArray smallSpaces smallSpace
sep words spaces
def breakUp (width : Nat) (words : Array String) : Array (Array String) := def breakUp (width : Nat) (words : Array String) : Array (Array String) :=
let (_, line, lines) := words.foldl let (_, line, lines) := words.foldl
(fun (left, line, lines) word => (λ(left, line, lines) word ↦
if word.length < left if word.length < left
then (left - (word.length + 1), line.push word, lines) then (left - (word.length + 1), line.push word, lines)
else (width - word.length, #[word], lines.push line)) else (width - word.length, #[word], lines.push line))
@ -49,20 +56,20 @@ def usage := "Usage: justify WIDTH"
def fail : IO UInt32 := do IO.println usage; return 1 def fail : IO UInt32 := do IO.println usage; return 1
def main : List String → IO UInt32 def main : List String → IO UInt32
| [width] => do | [width] =>
if let some width := width.toNat? if let some width := width.toNat?
then then do
let stdin ← IO.getStdin let stdin ← IO.getStdin
let mut remainder : Array String := #[] let mut remainder : Array String := #[]
repeat while true do
let line ← stdin.getLine let line ← stdin.getLine
if line.isEmpty then break if line.isEmpty then break
let lines := breakUp width (remainder ++ line.words) let lines := breakUp width (remainder ++ line.words)
if h : lines.size > 0 then if h : lines.size > 0 then
remainder := lines[lines.size-1] remainder := lines[lines.size-1]
for line in lines[0:lines.size-1] do for line in lines[0:lines.size-1] do
IO.println <| justify width line IO.println $ justify width line
IO.println <| sep remainder (fun _ => " ") IO.println $ String.intercalate " " remainder.toList
return 0 return 0
else fail else fail
| _ => fail | _ => fail

View file

@ -5,8 +5,3 @@ defaultTargets = ["justify"]
[[lean_exe]] [[lean_exe]]
name = "justify" name = "justify"
root = "Main" root = "Main"
[[require]]
name = "batteries"
scope = "leanprover-community"
rev = "main"

View file

@ -1 +1 @@
leanprover/lean4:v4.17.0-rc1 leanprover/lean4:4.15.0