• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jaeyson / freecodecamp_elixir / 2cc9dcc7fa8586528952c9ca8b488ffc49a3bd07

29 Jul 2024 09:42AM UTC coverage: 100.0%. Remained the same
2cc9dcc7fa8586528952c9ca8b488ffc49a3bd07

Pull #87

github

web-flow
Bump excoveralls from 0.18.1 to 0.18.2

Bumps [excoveralls](https://github.com/parroty/excoveralls) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/parroty/excoveralls/releases)
- [Changelog](https://github.com/parroty/excoveralls/blob/master/CHANGELOG.md)
- [Commits](https://github.com/parroty/excoveralls/compare/v0.18.1...v0.18.2)

---
updated-dependencies:
- dependency-name: excoveralls
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #87: Bump excoveralls from 0.18.1 to 0.18.2

87 of 87 relevant lines covered (100.0%)

2128.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/lib/freecodecamp_elixir/basic_algo.ex
1
defmodule FreecodecampElixir.BasicAlgo do
2
  @moduledoc """
3
  Documentation for Freecodecamp ([Basic Alogrithmic Scripting](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/#basic-algorithm-scripting)).
4
  """
5
  @moduledoc since: "0.1.0"
6

7
  @doc """
8
  The formula to convert from Celsius to Fahrenheit is the temperature in Celsius times `9/5`, plus `32`.
9

10
  Returns an integer.
11

12
  source: [Convert Celsius to Fahrenheit](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit)
13

14
  ## Examples
15

16
      iex> BasicAlgo.convert_to_f(30)
17
      86
18

19
  """
20
  @doc since: "0.1.0"
21
  @spec convert_to_f(integer) :: integer
22
  def convert_to_f(celsius), do: div(celsius * 9, 5) + 32
101✔
23

24
  @doc """
25
  Reverses a string.
26

27
  source: [Reverse a String](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/reverse-a-string)
28

29
  ## Examples
30

31
      iex> BasicAlgo.reverse_string("hello")
32
      "olleh"
33

34
  """
35
  @doc since: "0.1.0"
36
  @spec reverse_string(String.t()) :: String.t()
37
  # defdelegate reverse_string(str), to: String, as: :reverse
38
  def reverse_string(""), do: ""
101✔
39

40
  def reverse_string(<<letter::utf8, rest::binary>> = _string),
41
    do: reverse_string(rest) <> <<letter>>
2,544✔
42

43
  @doc """
44
  Factorialize a number
45

46
  source: [Factorialize a Number](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/factorialize-a-number)
47

48
  ## Examples
49

50
      iex> BasicAlgo.factorialize(0)
51
      1
52

53
      iex> BasicAlgo.factorialize(5)
54
      120
55

56
  """
57
  @doc since: "0.1.0"
58
  @spec factorialize(integer) :: integer
59
  def factorialize(0), do: 1
101✔
60

61
  def factorialize(number) when is_integer(number) do
62
    1..number
63
    |> Stream.filter(&(&1 !== 0))
50,949✔
64
    |> Enum.to_list()
65
    |> do_factorialize()
101✔
66
  end
67

68
  @spec do_factorialize([integer]) :: integer
69
  defp do_factorialize(list) when list === [], do: 1
101✔
70
  defp do_factorialize([head | tail]), do: head * do_factorialize(tail)
50,893✔
71

72
  @doc """
73
  Return the length of the longest word in the provided sentence.
74

75
  Returns an integer.
76

77
  source: [Find the Longest Word in a String](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/find-the-longest-word-in-a-string)
78

79
  ## Examples
80

81
      iex> BasicAlgo.find_longest_word_length("")
82
      0
83

84
      iex> BasicAlgo.find_longest_word_length("May the force be with you")
85
      5
86

87
  """
88
  @doc since: "0.1.0"
89
  @spec find_longest_word_length(String.t()) :: integer
90
  def find_longest_word_length(""), do: 0
101✔
91

92
  def find_longest_word_length(string) when is_binary(string) do
93
    string
94
    |> String.splitter([" "])
95
    |> Enum.map(&String.length(&1))
96
    |> Enum.max()
101✔
97
  end
98

99
  @doc """
100
  Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.
101

102
  source: [Return Largest Numbers in Arrays](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/return-largest-numbers-in-arrays)
103

104
  ## Examples
105

106
      iex> BasicAlgo.largest_of_four([])
107
      []
108

109
      iex> BasicAlgo.largest_of_four([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]])
110
      [25, 48, 21, -3]
111

112
  """
113
  @doc since: "0.1.0"
114
  @spec largest_of_four([integer]) :: [integer]
115
  def largest_of_four(list) do
116
    list
117
    |> Stream.filter(&(&1 !== []))
404✔
118
    |> Enum.to_list()
119
    |> do_largest_of_four()
102✔
120
  end
121

122
  @spec do_largest_of_four([integer]) :: [integer]
123
  defp do_largest_of_four([]), do: []
102✔
124

125
  defp do_largest_of_four([head | tail] = _list) do
126
    sorted_head = head |> Enum.sort(:desc) |> hd()
404✔
127

128
    [sorted_head | do_largest_of_four(tail)]
129
  end
130

131
  @doc """
132
  Return repeated string.
133

134
  source: [Repeat a String Repeat a String](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/repeat-a-string-repeat-a-string)
135

136
  ## Examples
137

138
      iex> BasicAlgo.repeat_string_num_times("abc", 2)
139
      "abcabc"
140

141
      iex> BasicAlgo.repeat_string_num_times("abc", 0)
142
      ""
143
      
144
      iex> BasicAlgo.repeat_string_num_times("", 100)
145
      ""
146
      
147
      iex> BasicAlgo.repeat_string_num_times("abc", -1)
148
      ""
149

150
  """
151
  @doc since: "0.1.0"
152
  @spec repeat_string_num_times(String.t(), integer) :: String.t()
153
  def repeat_string_num_times(_string, num) when num <= 0, do: ""
202✔
154
  def repeat_string_num_times("", _num), do: ""
1✔
155
  def repeat_string_num_times(string, 1), do: string
101✔
156

157
  def repeat_string_num_times(string, num) when num > 1 do
158
    string <> repeat_string_num_times(string, num - 1)
2,377✔
159
  end
160

161
  @doc """
162
  Returns true if the string in the first element of the array
163
  contains all of the letters of the string in the second
164
  element of the array.
165

166
  source: [Mutations](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/mutations)
167

168
  ## Examples
169

170
      iex> BasicAlgo.mutation(["hello", "Hey"])
171
      false
172

173
      iex> BasicAlgo.mutation(["hello", "neo"])
174
      false
175
      
176
      iex> BasicAlgo.mutation(["Noel", "Ole"])
177
      true
178

179
  """
180
  @doc since: "0.1.0"
181
  @spec mutation([String.t()]) :: boolean()
182
  def mutation(["", ""]), do: false
100✔
183
  def mutation(["", _source]), do: false
100✔
184
  def mutation([_target, ""]), do: false
100✔
185

186
  def mutation([target, source] = _list) do
187
    list =
103✔
188
      &(String.downcase(&1)
189
        |> String.split("", trim: true)
190
        |> Enum.uniq()
191
        |> Enum.sort())
1,726✔
192

193
    new_list = list.(target) |> Enum.filter(&(&1 in list.(source)))
103✔
194

195
    new_list == list.(source)
103✔
196
  end
197

198
  @doc """
199
  Truncate a string (first argument) if it is longer than
200
  the given maximum string length (second argument). Return
201
  the truncated string with a `...` ending.
202

203
  source: [Truncate a String](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/truncate-a-string)
204

205
  ## Examples
206

207
      iex> BasicAlgo.truncate_string("A-tisket a-tasket A green and yellow basket", 8)
208
      "A-tisket..."
209

210
      iex> BasicAlgo.truncate_string("Absolutely Longer", 2)
211
      "Ab..."
212
      
213
      iex> BasicAlgo.truncate_string("A-", 1)
214
      "A..."
215

216
      iex> BasicAlgo.truncate_string("A-tisket", -1)
217
      "..."
218

219
      iex> BasicAlgo.truncate_string("Hello", 50)
220
      "Hello..."
221

222
  """
223
  @doc since: "0.1.0"
224
  @spec truncate_string(String.t(), integer) :: String.t()
225
  def truncate_string(_words, len) when len <= 0, do: "..."
301✔
226
  def truncate_string("", _len), do: "..."
100✔
227

228
  def truncate_string(words, len) do
229
    case String.length(words) < len do
104✔
230
      true ->
231
        words <> "..."
41✔
232

233
      false ->
234
        words
235
        |> String.to_charlist()
236
        |> do_truncate_string(len)
237
        |> to_string()
63✔
238
        |> Kernel.<>("...")
63✔
239
    end
240
  end
241

242
  @spec do_truncate_string([char()], integer) :: list()
243
  defp do_truncate_string(_letter, 0), do: []
63✔
244

245
  defp do_truncate_string([head | tails] = _list, len),
1,027✔
246
    do: [[head] | do_truncate_string(tails, len - 1)]
247

248
  @doc """
249
  Return the lowest index at which a value (second argument) should be inserted into an array (first argument) once it has been **sorted**. The returned value should be a number.
250

251
  For example, `get_index_to_ins([1,2,3,4], 1.5)` should return 1 because it is greater than 1 (index 0), but less than 2 (index 1).
252

253
  Likewise, `get_index_to_ins([20,3,5], 19)` should return 2 because once the array has been sorted it will look like `[3,5,20]` and 19 is less than 20 (index 2) and greater than 5 (index 1).
254

255
  source: [Where do I Belong](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/where-do-i-belong)
256

257
  ## Examples
258

259
      iex> BasicAlgo.get_index_to_ins([1, 2, 3, 4], 1.5)
260
      1
261

262
      iex> BasicAlgo.get_index_to_ins([20, 3, 5], 19)
263
      2
264
      
265
      iex> BasicAlgo.get_index_to_ins([3, 10, 5], 3)
266
      0
267
      
268
  """
269
  @doc since: "0.1.0"
270
  @spec get_index_to_ins([integer], integer) :: integer
271
  def get_index_to_ins([], _value), do: 0
104✔
272

273
  def get_index_to_ins(list, value) do
274
    sorted_list = Enum.sort(list)
99✔
275

276
    result =
99✔
277
      for element <- sorted_list,
2,348✔
278
          element >= value,
279
          do:
280
            sorted_list
281
            |> Enum.find_index(&(&1 == round(element)))
34,783✔
282

283
    List.first(result) |> do_get_index_to_ins()
99✔
284
  end
285

286
  @spec do_get_index_to_ins(non_neg_integer | nil) :: non_neg_integer
287
  defp do_get_index_to_ins(nil), do: 0
5✔
288
  defp do_get_index_to_ins(result), do: result
94✔
289

290
  @doc """
291
  Check if a string (first argument, `string`) ends with the
292
  given target string (second argument, `target`).
293

294
  Returns a boolean.
295

296
  source: [Confirm the Ending](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/confirm-the-ending)
297

298
  ## Examples
299

300
      iex> BasicAlgo.confirm_ending("Bastian", "n")
301
      true
302

303
      iex> BasicAlgo.confirm_ending("Congratulation", "on")
304
      true
305
      
306
      iex> BasicAlgo.confirm_ending("Connor", "n")
307
      false
308
      
309
  """
310
  @doc since: "0.1.0"
311
  @spec confirm_ending(String.t(), String.t()) :: boolean()
312
  def confirm_ending(string, target)
150✔
313
      when byte_size(string) < byte_size(target) do
314
    false
315
  end
316

317
  def confirm_ending(string, target) do
318
    length = String.length(string) - String.length(target)
553✔
319
    <<_substr::binary-size(length), rest::binary>> = string
553✔
320
    rest === target
553✔
321
  end
322

323
  @doc """
324
  Returns the first element thats passes the `truth test` from a given function.
325

326
  source: [Finders Keepers](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/finders-keepers)
327

328
  ## Examples
329

330
      iex> BasicAlgo.find_element([1, 3, 5, 8, 9, 10], &Integer.mod(&1, 2) === 0)
331
      8
332

333
      iex> BasicAlgo.find_element([1, 3, 5, 9], &(Integer.mod(&1, 2) === 0))
334
      nil
335

336
      iex> BasicAlgo.find_element([], & &1 === 0)
337
      nil
338

339
  """
340
  @doc since: "0.1.0"
341
  @spec find_element(list(), function()) :: any()
342
  def find_element([], _fun), do: nil
110✔
343

344
  def find_element([head | _tail] = list, fun) do
345
    do_find_element(fun.(head), list, fun)
993✔
346
  end
347

348
  @spec do_find_element(boolean(), list(), function()) :: any()
349
  defp do_find_element(true, [head | _tail], _fun), do: head
193✔
350
  defp do_find_element(false, [_head | tail], fun), do: find_element(tail, fun)
800✔
351

352
  @doc """
353
  Check if a value is classified as a boolean primitive. Return true or false.
354

355
  source: [Boo who](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/boo-who)
356

357
  ## Examples
358

359
      iex> BasicAlgo.boo_who(true)
360
      true
361

362
      iex> BasicAlgo.boo_who(false)
363
      true
364

365
      iex> BasicAlgo.boo_who([])
366
      false
367

368
      iex> BasicAlgo.boo_who("a")
369
      false
370

371
  """
372
  @doc since: "0.1.0"
373
  @spec boo_who(any()) :: boolean()
374
  def boo_who(any) when is_boolean(any), do: true
4✔
375
  def boo_who(_not_boolean), do: false
9✔
376

377
  @doc """
378
  Capitalize each word in a sentence
379

380
  source: [Title Case a Sentence](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/title-case-a-sentence)
381

382
  ## Examples
383

384
      iex> BasicAlgo.title_case("I'm a little tea pot")
385
      "I'm A Little Tea Pot"
386

387
      iex> BasicAlgo.title_case("sHoRt AnD sToUt")
388
      "Short And Stout"
389

390
      iex> BasicAlgo.title_case("HERE IS MY HANDLE HERE IS MY SPOUT")
391
      "Here Is My Handle Here Is My Spout"
392

393
  """
394
  @doc since: "0.1.0"
395
  @spec title_case(String.t()) :: String.t()
396
  def title_case(""), do: ""
100✔
397

398
  def title_case(string) do
399
    do_title_case(~w(#{string}), "")
103✔
400
  end
401

402
  @spec do_title_case(String.t() | [], String.t()) :: String.t()
403
  defp do_title_case([], <<_::binary-size(1), string::binary>>), do: string
103✔
404

405
  defp do_title_case([head | tail] = _list, string) do
406
    <<first_letter::binary-size(1), rest::binary>> = head
5,016✔
407
    capitalized = ~s(#{string} #{String.upcase(first_letter)}#{String.downcase(rest)})
5,016✔
408
    do_title_case(tail, capitalized)
5,016✔
409
  end
410

411
  @doc """
412
  Inserts the 1st list in 2nd list at its index position (3rd param).
413
  Also an [SO link](https://stackoverflow.com/a/27420592/10250774) why doing
414
  binary search on linked list is slower. Used linear search instead.
415

416
  source: [Slice and Splice](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/slice-and-splice)
417

418
  ## Examples
419

420
      iex> BasicAlgo.franken_splice([1, 2, 3], [4, 5], 1)
421
      [4, 1, 2, 3, 5]
422

423
      iex> BasicAlgo.franken_splice([1, 2], ["a", "b"], 1)
424
      ["a", 1, 2, "b"]
425

426
      iex> BasicAlgo.franken_splice(["claw", "tentacle"], ["head", "shoulders", "knees", "toes"], 2)
427
      ["head", "shoulders", "claw", "tentacle", "knees", "toes"]
428

429
  """
430
  @doc since: "0.1.0"
431
  @spec franken_splice(Enumerable.t(), Enumerable.t(), integer) :: Enumerable.t()
432
  def franken_splice(list_a, list_b, el) when el >= 0 do
433
    do_franken_splice(el, list_a, [], list_b)
434
    |> List.flatten()
162✔
435
  end
436

437
  def franken_splice(list_a, list_b, el) when el < 0 do
438
    (length(list_b) + (el + 1))
439
    |> do_franken_splice(list_a, [], list_b)
440
    |> List.flatten()
141✔
441
  end
442

443
  @spec do_franken_splice(integer, list(), list(), list()) :: list()
444
  defp do_franken_splice(counter, list_a, list, list_b)
171✔
445
       when counter === 0,
446
       do: [list | [list_a | [list_b]]]
447

448
  defp do_franken_splice(counter, list_a, list, [h | t] = _list_b)
449
       when counter > 0,
450
       do: do_franken_splice(counter - 1, list_a, [list | [h]], t)
3,511✔
451

452
  defp do_franken_splice(_counter, list_a, list, list_b)
72✔
453
       when list_b === [],
454
       do: [list | [list_b | [list_a]]]
455

456
  defp do_franken_splice(_counter, list_a, list, list_b)
60✔
457
       when list === [],
458
       do: [list_a | [list | [list_b]]]
459

460
  @doc """
461
  Remove all falsy values from an array. Falsy values
462
  in JavaScript are `false, null, 0, "", undefined, and NaN`,
463
  only "", false, nil or 0 were implemented for simplicity
464
  reasons.
465

466
  source: [Falsy Bouncer](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/falsy-bouncer)
467

468

469
  ## Examples
470

471
      iex> BasicAlgo.bouncer([7, "ate", "", false, 9])
472
      [7, "ate", 9]
473

474
      iex> BasicAlgo.bouncer(["a", "b", "c"])
475
      ["a", "b", "c"]
476

477
      iex> BasicAlgo.bouncer([false, nil, 0, ""])
478
      []
479

480
      iex> BasicAlgo.bouncer([7, [], false, ""])
481
      [7, []]
482
  """
483
  @doc since: "0.1.0"
484
  @spec bouncer(list()) :: list()
485
  def bouncer(list), do: do_bouncer(list, [])
8✔
486

487
  @spec do_bouncer(list(), list()) :: list()
488
  defp do_bouncer(list, filtered_list) when list === [] do
489
    filtered_list
8✔
490
  end
491

492
  defp do_bouncer([head | tails] = _list, list) when head in ["", false, nil, 0] do
493
    do_bouncer(tails, list)
16✔
494
  end
495

496
  defp do_bouncer([head | tails] = _list, list) do
497
    do_bouncer(tails, List.flatten(list, [head]))
16✔
498
  end
499

500
  @doc """
501
  Splits a list (first argument) into groups the length
502
  of size (second argument) and returns them as a
503
  two-dimensional list.
504

505
  source: [Chunky Monkey](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/chunky-monkey)
506

507
  ## Examples
508

509
      iex> BasicAlgo.chunk_array_in_groups(["a", "b", "c", "d"], 2)
510
      [["a", "b"], ["c", "d"]]
511

512
      iex> BasicAlgo.chunk_array_in_groups([0, 1, 2, 3, 4, 5], 3)
513
      [[0, 1, 2], [3, 4, 5]]
514

515
      iex> BasicAlgo.chunk_array_in_groups([0, 1, 2, 3, 4, 5], 2)
516
      [[0, 1], [2, 3], [4, 5]]
517

518
  """
519
  @doc since: "0.1.0"
520
  @spec chunk_array_in_groups(list(), integer) :: [list()]
521
  def chunk_array_in_groups([], _size), do: []
5✔
522
  def chunk_array_in_groups(list, size) when size < 1, do: list
96✔
523

524
  def chunk_array_in_groups(list, size) do
525
    do_chunk_array_in_groups([], [], list, size, 0)
402✔
526
  end
527

528
  @spec do_chunk_array_in_groups(list(), list(), list(), integer, integer) :: list()
529
  defp do_chunk_array_in_groups(list_a, list_b, [], _, _) do
530
    list_a ++ [list_b]
402✔
531
  end
532

533
  defp do_chunk_array_in_groups(list_a, list_b, [h | t] = _, size, counter)
534
       when counter < size do
535
    do_chunk_array_in_groups(list_a, list_b ++ [h], t, size, counter + 1)
3,406✔
536
  end
537

538
  defp do_chunk_array_in_groups(list_a, list_b, [h | t] = _, size, counter)
539
       when counter === size do
540
    do_chunk_array_in_groups(list_a ++ [list_b], [h], t, size, 1)
549✔
541
  end
542
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc