kitty icon indicating copy to clipboard operation
kitty copied to clipboard

Add F# to kitty.yml

Open avborup opened this issue 3 years ago • 4 comments

It would be really great with an F# entry in the kitty.yml example file. Preferably this would use the fsc compiler executable.

avborup avatar Mar 09 '22 12:03 avborup

`

  • name: F# file_extension: fsx compile_command: fsc $SRC_PATH run_command: $EXE_PATH ` will that work?

OHNONOTAMOTH avatar Mar 10 '22 21:03 OHNONOTAMOTH

I participated in a Kattis contest and made a hacky, somewhat working solution for this issue. There are some interesting points from making it work on macOS at least:

  • From the F# help page on kattis.com, they use the fsharpc compiler.
  • To be able to run the executable, perhaps just in my case (using macOS), I had to get the mono runtime tool to use that to execute the binary file
  • F# solutions are heavily dependent on some fast IO. This means that in order not to confuse Kitty by placing the kattio.fs fast IO file provided by Kattis themselves, we can insert the code in the F# template file. Sadly the entrypoint function has to be the last in the file, so we can't hide the IO code. Although it works by creating a folder in a problem's directory and placing the kattio.fs file there, inserting a open Kattio statement in the top of the solution file and inserting ./<dir>/kattio.fs in the compile command before the <problem_name>.fs file.

I do have one problem though, and that is that I'm unable to submit .fs solutions. Kitty says that something went wrong with submitting the file, but I'm unable to debug.

This is how the yaml configuration looks like:

- name: FSharp
  file_extension: fs
  compile_command: fsharpc --optimize+ -r:System.Numerics "$SRC_FILE_NAME_NO_EXT".fs
  run_command: mono "$SRC_FILE_NAME_NO_EXT".exe

and this is how a template file could look like, with kattio.fs "included":

open System
open System.IO

// Copied the kattio.fs file from https://open.kattis.com/help/fsharp into this
// begin kattio.fs (namespace declaration excluded)
exception NoMoreTokensException

type Tokenizer(inStream : Stream) =

    let bs = new BufferedStream(inStream);
    let reader = new StreamReader(bs)

    let mutable tokens = Array.empty
    let mutable pos = 0

    let rec peek =
        function
        | () when pos < 0 -> None
        | () when pos < Array.length tokens ->
            let s = tokens.[pos]
            if s = "" then
                pos <- pos + 1
                peek ()
            else
                Some (tokens.[pos])
        | () ->
            let line = reader.ReadLine()
            if line = null then
                pos <- -1
                None
            else
                tokens <- line.Split (' ')
                pos <- 0
                peek ()

    new() = Tokenizer(Console.OpenStandardInput())

    member this.hasNext() = peek() <> None

    member this.Next() =
        match peek() with
        | None   -> raise NoMoreTokensException
        | Some s -> pos <- pos + 1; s


type Scanner(inStream : Stream) =
    inherit Tokenizer(inStream)

    new() = Scanner(Console.OpenStandardInput())

    member this.NextInt() = this.Next() |> int
    member this.NextLong() = this.Next() |> int64
    member this.NextFloat() = this.Next() |> float
    member this.NextDouble() = this.Next() |> double

type BufferedStdoutWriter() =
    inherit StreamWriter(new BufferedStream(Console.OpenStandardOutput()))
// end kattio.fs

[<EntryPoint>]
let main argv =
    let scanner = Scanner()
    0

andreaswachs avatar Mar 12 '22 20:03 andreaswachs

@andreaswachs thanks for the contribution!

To be able to run the executable, perhaps just in my case (using macOS), I had to get the mono runtime tool to use that to execute the binary file

Huh, that's weird. Have you tried the following?

  run_command: $EXE_PATH

I don't have a mac, so I am unable to test at the moment. If the output file produced by fsharpc doesn't match $EXE_PATH, you should be able to add --out:$EXE_PATH to the compile command (detailed in F# compiler options).

F# solutions are heavily dependent on some fast IO. This means [...]

Unfortunately kitty doesn't support multi-file submissions. That would be a really nice addition, though. And thanks for including a Kattio example - if F# users find this issue, it will be useful.

I do have one problem though, and that is that I'm unable to submit .fs solutions. Kitty says that something went wrong with submitting the file, but I'm unable to debug.

I believe that is what the following comment from the example file addresses:

  # Languages must contain a display name that matches Kattis' name for the
  # language exactly - i.e. the precise text in the language dropdown menu at
  # https://open.kattis.com/submit. If you get an error saying "something went
  # wrong during submission", this may be a likely reason!

I think the issue will be fixed if the name is changed from FSharp to F#.

avborup avatar Mar 13 '22 21:03 avborup

@OHNONOTAMOTH that seems pretty good.

I think .fsx should be changed to .fs - I'm not sure if Kattis accepts fsx script files, but I think fs files are more appropriate here.

Have you tested this? If so, do you mind sharing how you got your hands on fsc and compiled your file? I tried to download it from NuGet here, but I got an error:

> fsc .\eyeofsauron.fs

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

avborup avatar Mar 13 '22 21:03 avborup