ELM recursive iteration constructor

I have a function computeNextValue such as for a given number x, it computes the number y, by additioning all digits of number x to itself
ex : Given x = 45: y = 54 = 4 + 5 + 45

computeNextValue : Int → Int
computeNextValue x =
List.sum (numberToList x) + x

and i want to mplement the function computeNextValueWithIteration with the following signature :

computeNextValueWithIteration : Int → Int → Int

The first parameter will be an “iteration” value, the second parameter will be the “number” value such that I compute “iteration” number of times to get the result y.

ex : Given x = 123 and iteration = 3, you would compute why like this :

  • Iteration 1 : 129 = 1 + 2 + 3 + 123
  • Iteration 2 : 141 = 1 + 2 + 9 + 129
  • Iteration 3 : 147 = 1 + 4 + 1 + 141

y = 147

my code
-- The name of the module must always be the same name as the file !
module Main exposing (main)

{-
  All imports we need, nothing more to add for this quest
  Checkout https://elm-lang.org/docs and https://package.elm-lang.org/ when needed
-}
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onSubmit, onInput)
import String exposing (fromInt)
import Basics
import Array exposing (Array)


type alias Model =
  { input : Maybe Int
  , output : Maybe Int
  }

-- We initialize the default value of our model
init : Model
init =
  { input = Nothing
  , output = Nothing
  }

-- We render a view given the model
view : Model -> Html Msg
view model =
  div []
  [  input [ type_ "number", placeholder "Enter a number", value (maybeIntToString model.input), onInput SetValue ] []
  ,  br [] []
  ,  button [ onClick SubmitForm, id "compute" ] [text "Calculate"]
  ,  div [] [ text "output : ", span [id "output"] [ text <| maybeIntToString model.output]]
  ]

-- Helper function
maybeIntToString : Maybe Int -> String
maybeIntToString model =
  case model of
    Nothing -> ""
    Just v -> fromInt v

type Msg
  = NoOp
  | SubmitForm
  | SetValue String

update : Msg -> Model -> Model
update msg model =
  -- With Debug.log we log into the browser console, see https://package.elm-lang.org/packages/elm-lang/core/3.0.0/Debug
  case Debug.log "msg" msg of
    NoOp ->
      model
    SetValue v ->
      { model | input = String.toInt v }
    SubmitForm ->
      { model | output = Maybe.map computeNextValue model.input }


-- To implement
computeNextValue : Int -> Int
computeNextValue x =
   List.sum (numberToList x) + x


numberToList : Int -> List Int
numberToList number =
    String.fromInt number -- convert our Int to a String
        |> String.split ""
        |> List.filterMap String.toInt


computeNextValueWithIteration : Int -> Int -> Int
computeNextValueWithIteration n x =
    List.foldl (\_ sum -> computeNextValue sum) x (List.repeat n 0)


main : Program () (Model) Msg
main =
  Browser.sandbox({ init = init, view = view, update = update})

i want to con sider this steps

  • Add an iteration field of type Int to the model
  • Initialize it to the value 0 where required
  • Add the data constructor SetIteration String to the Msg type
  • Add the following code to the update function
SetIteration v ->
{ model | iteration = Maybe.withDefault 0 <| String.toInt v}
  • Modify the update function on the SubmitForm case to use the function computeNextValueWithIteration `instead of the` computeNextValue implemented on quest 1
  • Modify the view function to add an input (html) element of type number with the id iteration . Do not forget to set the onInput event correctly. Use the imported function fromInt to convert the integer to string

Something like this: iterations ?

module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Attributes as Attr
import Html.Events exposing (onInput, onSubmit)


type alias Model =
    { iterations : Int
    , input : Int
    , output : Int
    }


initialModel : Model
initialModel =
    { iterations = 0
    , input = 0
    , output = 0
    }


type Msg
    = Iterations String
    | Input String
    | Compute


update : Msg -> Model -> Model
update msg model =
    case msg of
        Iterations iterations ->
            { model | iterations = Maybe.withDefault 0 <| String.toInt iterations }

        Input input ->
            { model | input = Maybe.withDefault 0 <| String.toInt input }

        Compute ->
            { model | output = computeNextValueWithIteration model.iterations model.input}


computeNextValueWithIteration : Int -> Int -> Int
computeNextValueWithIteration iterations input =
    case iterations of
        0 -> input
        _ -> computeNextValueWithIteration (iterations - 1) (computeNextValue input)

computeNextValue : Int -> Int
computeNextValue input =
    String.fromInt input
        |> String.split ""
        |> List.filterMap String.toInt
        |> List.sum
        |> (+) input

view : Model -> Html Msg
view model =
    Html.form [ onSubmit Compute ]
        [ Html.label
            [ Attr.for "iterations" ]
            [ Html.text "# iterations" ]
        , Html.input
            [ Attr.type_ "number"
            , Attr.id "iterations"
            , Attr.value <| String.fromInt model.iterations
            , onInput Iterations
            ]
            []
        , Html.label
            [ Attr.for "number_input" ]
            [ Html.text "input" ]
        , Html.input
            [ Attr.type_ "number"
            , Attr.id "number_input"
            , Attr.value <| String.fromInt model.input
            , onInput Input
            ]
            []
        , Html.button [] [ Html.text "compute" ]
        , Html.text <| String.fromInt model.output
        ]


main : Program () Model Msg
main =
    Browser.sandbox
        { init = initialModel
        , view = view
        , update = update
        }

Thank youu very much

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.