├── .github └── FUNDING.yml ├── .gitignore ├── Build.PL ├── Changes ├── LICENSE ├── MANIFEST ├── MANIFEST.SKIP ├── Makefile.PL ├── NUMBER_THEORY_TUTORIAL.md ├── README.md ├── TODO ├── TUTORIAL.md ├── _config.yml ├── bin └── sidef ├── lib ├── Sidef.pm ├── Sidef.pod └── Sidef │ ├── Deparse │ ├── Perl.pm │ └── Sidef.pm │ ├── Math │ ├── Math.pm │ └── Math.pod │ ├── Module │ ├── Func.pm │ └── OO.pm │ ├── Object │ ├── Convert.pm │ ├── Convert.pod │ ├── Enumerator.pm │ ├── Enumerator.pod │ ├── Lazy.pm │ ├── Lazy.pod │ ├── LazyMethod.pm │ ├── LazyMethod.pod │ ├── Object.pm │ └── Object.pod │ ├── Optimizer.pm │ ├── Parser.pm │ ├── Sys │ ├── Sig.pm │ ├── Sig.pod │ ├── Sys.pm │ └── Sys.pod │ ├── Time │ ├── Date.pm │ ├── Date.pod │ ├── Time.pm │ └── Time.pod │ ├── Types │ ├── Array │ │ ├── Array.pm │ │ ├── Array.pod │ │ ├── Matrix.pm │ │ ├── Matrix.pod │ │ ├── Pair.pm │ │ ├── Pair.pod │ │ ├── Vector.pm │ │ └── Vector.pod │ ├── Block │ │ ├── Block.pm │ │ ├── Block.pod │ │ ├── Fork.pm │ │ ├── Fork.pod │ │ ├── Try.pm │ │ └── Try.pod │ ├── Bool │ │ ├── Bool.pm │ │ └── Bool.pod │ ├── Glob │ │ ├── Backtick.pm │ │ ├── Backtick.pod │ │ ├── Dir.pm │ │ ├── Dir.pod │ │ ├── DirHandle.pm │ │ ├── DirHandle.pod │ │ ├── File.pm │ │ ├── File.pod │ │ ├── FileHandle.pm │ │ ├── FileHandle.pod │ │ ├── Pipe.pm │ │ ├── Pipe.pod │ │ ├── Socket.pm │ │ ├── Socket.pod │ │ ├── SocketHandle.pm │ │ ├── SocketHandle.pod │ │ ├── Stat.pm │ │ └── Stat.pod │ ├── Hash │ │ ├── Hash.pm │ │ └── Hash.pod │ ├── Null │ │ ├── Null.pm │ │ └── Null.pod │ ├── Number │ │ ├── Complex.pm │ │ ├── Complex.pod │ │ ├── Fraction.pm │ │ ├── Fraction.pod │ │ ├── Gauss.pm │ │ ├── Gauss.pod │ │ ├── Mod.pm │ │ ├── Mod.pod │ │ ├── Number.pm │ │ ├── Number.pod │ │ ├── Polynomial.pm │ │ ├── Polynomial.pod │ │ ├── PolynomialMod.pm │ │ ├── PolynomialMod.pod │ │ ├── Quadratic.pm │ │ ├── Quadratic.pod │ │ ├── Quaternion.pm │ │ └── Quaternion.pod │ ├── Perl │ │ ├── Perl.pm │ │ └── Perl.pod │ ├── Range │ │ ├── Range.pm │ │ ├── Range.pod │ │ ├── RangeNumber.pm │ │ ├── RangeNumber.pod │ │ ├── RangeString.pm │ │ └── RangeString.pod │ ├── Regex │ │ ├── Match.pm │ │ ├── Match.pod │ │ ├── Regex.pm │ │ └── Regex.pod │ ├── Set │ │ ├── Bag.pm │ │ ├── Bag.pod │ │ ├── Set.pm │ │ └── Set.pod │ └── String │ │ ├── String.pm │ │ └── String.pod │ └── Variable │ ├── GetOpt.pm │ ├── GetOpt.pod │ ├── NamedParam.pm │ └── NamedParam.pod ├── scripts ├── Applications │ ├── Gift match │ │ ├── giftmatch.sf │ │ ├── input.txt │ │ └── output.txt │ ├── Pure OO │ │ ├── booleans.sf │ │ ├── if_statement.sf │ │ └── numbers.sf │ ├── fdf.sf │ └── resistor_mesh.sf ├── Expensive │ ├── benford_s_law.sf │ ├── binary_multiplier.sf │ ├── calendar.sf │ ├── calendar_all_uppercase.sf │ ├── chebyshev_factorization_method.sf │ ├── closed_form_fibonacci.sf │ ├── coin_change.sf │ ├── concurrent_computing.sf │ ├── dice_game_solver.sf │ ├── ekg_sequence_convergence.sf │ ├── factorial_approximations.sf │ ├── fforks.sf │ ├── fibonacci_validation.sf │ ├── fibonacci_word.sf │ ├── fork.sf │ ├── gauss_logarithm_approx.sf │ ├── genetic_algorithm.sf │ ├── julia_set.sf │ ├── kd_tree.sf │ ├── knapsack_problem_0_1.sf │ ├── knapsack_problem_bounded.sf │ ├── knapsack_problem_unbounded.sf │ ├── knuth_power_tree.sf │ ├── long_multiplication.sf │ ├── ludic_numbers.sf │ ├── md5.sf │ ├── multiplicative_digital_root.sf │ ├── normal_distribution.sf │ ├── numerical_integration.sf │ ├── parallel_calculations.sf │ ├── prime_permutations.sf │ ├── quicksort_in_parallel.sf │ ├── root_of_a_function.sf │ ├── smart_word_wrap.sf │ ├── smart_word_wrap_lazy.sf │ ├── subset_sum_problem.sf │ ├── sudoku_solver.sf │ ├── sum_and_product_puzzle.sf │ ├── thiele_interpolation_formula.sf │ ├── zebra_puzzle.sf │ └── zhang_suen_thinning_algorithm.sf ├── Extended tests │ ├── almost_and_omega_primes.sf │ ├── binomialmod.sf │ ├── carmichael_with_n_factors.sf │ ├── chebyshev_factorization_method.sf │ ├── combinatorics.sf │ ├── digits2num.pl │ ├── elementary.sf │ ├── fermat_pseudoprimes.sf │ ├── fermat_pseudoprimes_to_base_n.sf │ ├── fermat_with_n_factors.sf │ ├── fermat_with_n_factors_to_base_n.sf │ ├── floor_ceil.sf │ ├── inverse_of_multiplicative_functions.sf │ ├── inverse_sigma.sf │ ├── is_almost_prime.sf │ ├── is_carmichael.sf │ ├── is_omega_prime.sf │ ├── is_over_psp.sf │ ├── is_super_psp.sf │ ├── lucas_carmichael_negative.sf │ ├── lucas_carmichael_positive.sf │ ├── lucas_carmichael_with_n_factors.sf │ ├── lucas_sequences.sf │ ├── mertens_function.sf │ ├── misc_number_tests.sf │ ├── nth_prime.sf │ ├── nth_prime_near_powers_of_10.sf │ ├── number_methods.sf │ ├── oeis_sequences.sf │ ├── prime_bounds.sf │ ├── prime_count.sf │ ├── prime_power_count.sf │ ├── pseudoprimes.sf │ ├── range_sum.sf │ ├── sqrtmod.pl │ ├── squarefree_pseudoprimes.sf │ ├── strong_fermat_pseudoprimes_to_base_n.sf │ ├── strong_fermat_with_n_factors.sf │ ├── strong_fermat_with_n_factors_to_base_n.sf │ ├── sumdigits.pl │ ├── tie_berkeley_db.sf │ ├── tie_berkeley_db_recno.sf │ └── tie_gdbm_db.sf ├── Games │ ├── 24_game.sf │ ├── 24_game_solve.sf │ ├── 24_game_solve_no_eval.sf │ ├── asciiplanes-player.sf │ ├── asciiplanes.sf │ ├── bulls_and_cows.sf │ ├── bulls_and_cows_player.sf │ ├── conway_s_game_of_life.sf │ ├── forest_fire.sf │ ├── forest_fire_old.sf │ ├── guess_the_number.sf │ ├── guess_the_number_with_feedback.sf │ ├── guess_the_number_with_feedback_player.sf │ ├── iq_puzzle.sf │ ├── pig_the_dice_game_player.sf │ ├── rock-paper-scissors.sf │ ├── snake_game.sf │ └── snake_game_oo.sf ├── Graphical │ ├── LSystem │ │ ├── LSystem.sf │ │ └── Turtle.sf │ ├── barnsley_fern.sf │ ├── barnsley_fern_ifs.sf │ ├── chaos_game.sf │ ├── circle_from_polygons.sf │ ├── color_bars.sf │ ├── color_wheel.sf │ ├── death_star.sf │ ├── draw_a_sphere.sf │ ├── fbrowse_tray.sf │ ├── fractal_tree.sf │ ├── hello_world_graphical.sf │ ├── hello_world_graphical_1.sf │ ├── honeycombs.sf │ ├── kronecker_fractal.sf │ ├── lsystem_hilbert_curve.sf │ ├── lsystem_koch_snowflake.sf │ ├── lsystem_penrose_tiling.sf │ ├── lsystem_plant_1.sf │ ├── lsystem_plant_2.sf │ ├── lsystem_sierpinski_triangle.sf │ ├── lsystem_tree.sf │ ├── munching_squares.sf │ ├── pendulum_animation.sf │ ├── plasma_effect.sf │ ├── ppm_palette.sf │ ├── pythagoras_tree.sf │ ├── sierpinski_pentagon.sf │ ├── sierpinski_triangle_graphical.sf │ ├── simple_windowed_application.sf │ ├── tree_ifs.sf │ ├── ulam_spiral.sf │ ├── user_input.sf │ ├── window_creation.sf │ ├── window_creation_1.sf │ └── yin_and_yang.sf ├── Interactive │ ├── cosmic_calendar.sf │ ├── draw_a_clock.sf │ ├── integer_comparison.sf │ ├── menu.sf │ ├── pi.sf │ ├── sparkline_in_unicode.sf │ ├── temperature_conversion.sf │ ├── user_input_text.sf │ └── user_input_text_1.sf ├── RosettaCode │ ├── 9_billion_names.sf │ ├── A_star_algorithm.sf │ ├── MRG32k3a.sf │ ├── PCG32.sf │ ├── Splitmix64.sf │ ├── Xorshift_star.sf │ ├── abc_problem.sf │ ├── almost_prime.sf │ ├── almost_prime_fast.sf │ ├── angle_difference_between_two_bearings.sf │ ├── append_to_text_file.sf │ ├── apply_a_digital_filter.sf │ ├── arithmetic-geometric_mean.sf │ ├── arithmetic_complex.sf │ ├── averages_arithmetic_mean.sf │ ├── averages_mean_time_of_day.sf │ ├── averages_mode.sf │ ├── averages_mode_1.sf │ ├── averages_pythagorean_means.sf │ ├── averages_root_mean_square.sf │ ├── avl_tree.sf │ ├── binary_digits.sf │ ├── binary_search.sf │ ├── binary_search_1.sf │ ├── bitwise_operations.sf │ ├── boolean_values.sf │ ├── boolean_values_1.sf │ ├── brace_expansion.sf │ ├── brazilian_numbers.sf │ ├── burrows_wheeler_transform.sf │ ├── burrows_wheeler_transform_fast.sf │ ├── cantor_set.sf │ ├── case-sensitivity_of_identifiers.sf │ ├── catalan_numbers.sf │ ├── catalan_numbers_1.sf │ ├── catalan_numbers_pascal_triangle.sf │ ├── catamorphism.sf │ ├── character_codes.sf │ ├── check_machin_like_formulas.sf │ ├── check_that_file_exists.sf │ ├── cheryl_s_birthday.sf │ ├── chi_squared_test.sf │ ├── cholesky_decomposition.sf │ ├── cipolla_algorithm.sf │ ├── classes.sf │ ├── closest_pair_problem.sf │ ├── closures_value_capture.sf │ ├── compare_a_list_of_strings.sf │ ├── compare_a_list_of_strings_1.sf │ ├── compile-time_calculation.sf │ ├── compile-time_calculation_1.sf │ ├── compound_data_type.sf │ ├── conjugate_transpose.sf │ ├── constrained_random_points_on_a_circle.sf │ ├── continued_fractions_from_rationals.sf │ ├── convert_decimal_number_to_rational.sf │ ├── convert_seconds_to_compound_duration.sf │ ├── convex_hull.sf │ ├── copy_a_string.sf │ ├── count_in_factors.sf │ ├── count_occurrences_of_a_substring.sf │ ├── count_the_coins.sf │ ├── create_an_html_table.sf │ ├── cumulative_standard_deviation.sf │ ├── currency.sf │ ├── date_format.sf │ ├── de_polignac_numbers.sf │ ├── decimal_float_to_binary.sf │ ├── delete_a_file.sf │ ├── deming_s_funnel.sf │ ├── determine_if_a_string_is_numeric.sf │ ├── dice_game_probabilities.sf │ ├── digital_root.sf │ ├── dijkstra_s_algorithm.sf │ ├── dinesman_problem_parsing.sf │ ├── dinesman_problem_simple.sf │ ├── dinesman_problem_simple_2.sf │ ├── diversity_prediction_theorem.sf │ ├── dot_product.sf │ ├── elliptic_curve_arithmetic.sf │ ├── emirp_primes.sf │ ├── empty_directory.sf │ ├── empty_directory_1.sf │ ├── entropy.sf │ ├── entropy_narcissist.sf │ ├── enumerations.sf │ ├── enumerations_1.sf │ ├── equilibrium_index.sf │ ├── euler_method.sf │ ├── extract_file_extension.sf │ ├── extreme_floating_point_values.sf │ ├── factorial.sf │ ├── factorions.sf │ ├── factors_of_a_mersenne_number.sf │ ├── factors_of_an_integers.sf │ ├── faulhaber_s_formula_2.sf │ ├── fibonacci_n-step_number_sequence.sf │ ├── fibonacci_sequence.sf │ ├── fibonacci_sequence_1.sf │ ├── fibonacci_sequence_2.sf │ ├── fibonacci_sequence_3.sf │ ├── file_modification_time.sf │ ├── file_size.sf │ ├── filter.sf │ ├── find_common_directory_path.sf │ ├── first-class_functions.sf │ ├── first_class_environments.sf │ ├── five_weekends.sf │ ├── flatten_a_list.sf │ ├── floyd_warshall_algorithm.sf │ ├── formatted_numeric_output.sf │ ├── formatted_numeric_output_1.sf │ ├── free_polyominoes_enumeration.sf │ ├── french_republican_calendar.sf │ ├── function_composition.sf │ ├── function_definition.sf │ ├── function_frequency.sf │ ├── gamma_function.sf │ ├── gamma_function_1.sf │ ├── gauss_jordan_matrix_inversion.sf │ ├── general_fizzbuzz.sf │ ├── generate_lower_case_ascii_alphabet.sf │ ├── generator_exponential.sf │ ├── generic_swap.sf │ ├── generic_swap_1.sf │ ├── get_system_command_output.sf │ ├── get_system_command_output_1.sf │ ├── greatest_common_divisor.sf │ ├── greatest_common_divisor_1.sf │ ├── greatest_element_of_a_list.sf │ ├── hash_from_two_arrays.sf │ ├── hash_join.sf │ ├── haversine_formula.sf │ ├── haversine_formula_2.sf │ ├── hickerson_series_of_almost_integers.sf │ ├── higher-order_functions.sf │ ├── history_variables.sf │ ├── holidays_related_to_easter.sf │ ├── horizontal_sundial_calculations.sf │ ├── hostname.sf │ ├── identity_matrix.sf │ ├── imaginary_base_numbers.sf │ ├── infinity.sf │ ├── inheritance_multiple.sf │ ├── inheritance_single.sf │ ├── intersection_of_two_lines.sf │ ├── kaprekar_numbers.sf │ ├── knapsack_problem_continuous.sf │ ├── knight_s_tour.sf │ ├── kolakoski_sequence.sf │ ├── largest_int_from_concatenated_ints.sf │ ├── last_sunday_of_each_month.sf │ ├── left_factorials.sf │ ├── left_factorials_1.sf │ ├── letter_frequency.sf │ ├── levenshtein_distance.sf │ ├── levenshtein_distance_1.sf │ ├── levenshtein_distance_2.sf │ ├── levenshtein_distance_alignment.sf │ ├── line_plane_intersection.sf │ ├── lis_dynamic_programming.sf │ ├── lis_patience_sorting.sf │ ├── list_rooted_trees.sf │ ├── literals_floating_point.sf │ ├── literals_integer.sf │ ├── literals_string.sf │ ├── literals_string_1.sf │ ├── literals_string_2.sf │ ├── logical_operations.sf │ ├── long_multiplication.sf │ ├── long_multiplication_1.sf │ ├── longest_common_prefix.sf │ ├── longest_common_substring.sf │ ├── look-and-say_sequence.sf │ ├── loop_over_multiple_arrays_simultaneously.sf │ ├── loops_break.sf │ ├── loops_continue.sf │ ├── loops_do-while.sf │ ├── loops_downward_for.sf │ ├── loops_for.sf │ ├── loops_for_1.sf │ ├── loops_for_2.sf │ ├── loops_for_with_a_specified_step.sf │ ├── loops_foreach.sf │ ├── loops_foreach_1.sf │ ├── loops_n_plus_one_half.sf │ ├── loops_nested.sf │ ├── loops_while.sf │ ├── lu_decomposition.sf │ ├── luhn_test_of_credit_card_numbers.sf │ ├── lzw_compression.sf │ ├── map_range.sf │ ├── matrix_multiplication.sf │ ├── matrix_transposition.sf │ ├── maze_generation.sf │ ├── md5.sf │ ├── md5_1.sf │ ├── middle_three_digits.sf │ ├── modular_arithmetic.sf │ ├── modular_exponentiation.sf │ ├── modular_inverse.sf │ ├── most_frequent_k_chars_distance.sf │ ├── move_to_front_algorithm_1.sf │ ├── move_to_front_algorithm_2.sf │ ├── multifactorial.sf │ ├── multiple_distinct_objects.sf │ ├── multiplication_tables.sf │ ├── multiplicative_order.sf │ ├── multisplit.sf │ ├── natural_sorting.sf │ ├── negative_base_numbers.sf │ ├── nested_function.sf │ ├── non_decimal_radices_convert.sf │ ├── nth.sf │ ├── nth_root.sf │ ├── orbital_elements.sf │ ├── orbital_elements_2.sf │ ├── orbital_elements_3.sf │ ├── order_disjoint_list_items.sf │ ├── ordered_partitions.sf │ ├── pangram_checker.sf │ ├── partial_function_application.sf │ ├── pascal_s_triangle.sf │ ├── pascal_s_triangle_puzzle.sf │ ├── perfect_shuffle.sf │ ├── perlin_noise.sf │ ├── permutations_by_swapping.sf │ ├── permutations_with_some_identical_elements.sf │ ├── pernicious_numbers.sf │ ├── phrase_reversals.sf │ ├── pick_random_element.sf │ ├── playfair_cipher.sf │ ├── playing_cards.sf │ ├── pointers_and_references.sf │ ├── polymorphic_copy.sf │ ├── polymorphism.sf │ ├── polynomial_synthetic_division.sf │ ├── price_fraction.sf │ ├── primality_by_trial_division.sf │ ├── priority_queue.sf │ ├── probabilistic_choice.sf │ ├── problem_of_apollonius.sf │ ├── program_name.sf │ ├── quaternion_type.sf │ ├── queue_definition.sf │ ├── queue_definition_2.sf │ ├── quickselect_algorithm.sf │ ├── quine_1.sf │ ├── ramer_line_simplification.sf │ ├── ramsey_s_theorem.sf │ ├── random_number_generator__device_.sf │ ├── range_expansion.sf │ ├── ranking_methods.sf │ ├── read_a_file_line_by_line.sf │ ├── read_a_file_line_by_line_1.sf │ ├── read_a_specific_line_from_a_file.sf │ ├── read_entire_file.sf │ ├── real_constants_and_functions.sf │ ├── reduced_row_echelon_form.sf │ ├── regular_expressions.sf │ ├── regular_expressions_1.sf │ ├── regular_expressions_2.sf │ ├── remove_duplicate_elements.sf │ ├── rename_a_file.sf │ ├── rep-string.sf │ ├── repeat.sf │ ├── repeat_a_string.sf │ ├── respond_to_an_unknown_method_call.sf │ ├── return_multiple_values.sf │ ├── reverse_a_string.sf │ ├── reverse_words_in_a_string.sf │ ├── rice_coding.sf │ ├── riordan_numbers.sf │ ├── roots_of_a_quadratic_function.sf │ ├── roots_of_unity_1.sf │ ├── rpn_calculator_algorithm.sf │ ├── rpn_to_infix_conversion.sf │ ├── runge-kutta_method.sf │ ├── runtime_evaluation.sf │ ├── runtime_evaluation_in_an_environment.sf │ ├── s_expressions.sf │ ├── sailors_coconuts_and_monkey.sf │ ├── search_a_list.sf │ ├── search_a_list_1.sf │ ├── secure_temporary_file.sf │ ├── sedols.sf │ ├── send_an_unknown_method_call.sf │ ├── sequence_of_primes_by_trial_division.sf │ ├── set_consolidation.sf │ ├── sha-1.sf │ ├── sha-256.sf │ ├── short-circuit_evaluation.sf │ ├── show_the_epoch.sf │ ├── shunting-yard_algorithm.sf │ ├── sidef_3d_ascii.sf │ ├── sieve_of_eratosthenes.sf │ ├── simulated_annealing.sf │ ├── singleton.sf │ ├── singly-linked_list_element_definition.sf │ ├── singly-linked_list_element_insertion.sf │ ├── site_percolation.sf │ ├── smallest_number_with_exactly_n_divisors.sf │ ├── smith_numbers.sf │ ├── sort_a_list_of_object_identifiers.sf │ ├── sort_an_integer_array.sf │ ├── sort_disjoint_sublist.sf │ ├── sort_stability.sf │ ├── sort_three_variables.sf │ ├── sort_using_a_custom_comparator.sf │ ├── sorting_algorithms_bubble_sort.sf │ ├── sorting_algorithms_circlesort.sf │ ├── sorting_algorithms_cocktail_sort.sf │ ├── sorting_algorithms_comb_sort.sf │ ├── sorting_algorithms_counting_sort.sf │ ├── sorting_algorithms_gnome_sort.sf │ ├── sorting_algorithms_heapsort.sf │ ├── sorting_algorithms_insertion_sort.sf │ ├── sorting_algorithms_merge_sort.sf │ ├── sorting_algorithms_merge_sort_2.sf │ ├── sorting_algorithms_patience_sort.sf │ ├── sorting_algorithms_quicksort.sf │ ├── sorting_algorithms_radix_sort.sf │ ├── sorting_algorithms_selection_sort.sf │ ├── sorting_algorithms_shell_sort.sf │ ├── sorting_algorithms_sleep_sort.sf │ ├── sorting_algorithms_stooge_sort.sf │ ├── sorting_algorithms_strand_sort.sf │ ├── spiral_matrix.sf │ ├── split_repchar_string.sf │ ├── square_but_not_cube.sf │ ├── stable_marriage_problem.sf │ ├── stack.sf │ ├── stack_1.sf │ ├── standard_deviation.sf │ ├── standard_deviation_2.sf │ ├── stem_and_leaf_plot.sf │ ├── string_comparison.sf │ ├── sub-unit_squares.sf │ ├── substitution_cipher.sf │ ├── suffix_tree.sf │ ├── sum_digits_of_an_integer.sf │ ├── sutherland_hodgman.sf │ ├── tarjan_s_algorithm.sf │ ├── taxicab_numbers.sf │ ├── ternary_and_binary_palindrome.sf │ ├── text_processing_1.sf │ ├── the_isaac_cipher.sf │ ├── thue_morse.sf │ ├── tonelli_shanks_algorithm.sf │ ├── top_rank_per_group.sf │ ├── truncatable_primes.sf │ ├── universal_turing_machine.sf │ ├── utf8_encode_decode.sf │ ├── van_der_corput_sequence.sf │ ├── variable_length_quantity.sf │ ├── vogel_s_approximation_method.sf │ ├── vogel_s_approximation_method_2.sf │ ├── walk_a_dir_non_recursively.sf │ ├── water_collected_between_towers.sf │ ├── word_break_problem.sf │ ├── word_wrap.sf │ ├── zeckendorf_number_representation.sf │ └── zig-zag_matrix.sf ├── Tests │ ├── Lingua │ │ └── RO │ │ │ └── Numbers.sm │ ├── Module │ │ ├── Bar.sm │ │ ├── Fact.sm │ │ ├── Fib.sm │ │ ├── Foo.sm │ │ ├── Test.sm │ │ └── YouTube.sm │ ├── almost_and_omega_primes.sf │ ├── amb.sf │ ├── amb_nested_loops.sf │ ├── anonymous_recursion.sf │ ├── arithmetic_derivative.sf │ ├── arithmetic_evaluation.sf │ ├── arithmetic_geometric_mean.sf │ ├── array_and_hash_lookup.sf │ ├── array_and_hash_lvalues.sf │ ├── array_any_all.sf │ ├── array_autovivification.sf │ ├── array_binary_search.sf │ ├── array_binsert.sf │ ├── array_compare.sf │ ├── array_flattening.sf │ ├── array_index_bindex.sf │ ├── array_unique.sf │ ├── array_xor.sf │ ├── array_zipping.sf │ ├── arrays.sf │ ├── autovivification.sf │ ├── averages_mode.sf │ ├── bags_1.sf │ ├── bags_2.sf │ ├── bags_3.sf │ ├── balanced_brakets.sf │ ├── bare_multiplication.sf │ ├── base64_decoder.sf │ ├── base_conversions.sf │ ├── basic_interpreter.sf │ ├── beadsort.sf │ ├── best_shuffle.sf │ ├── binary_search.sf │ ├── binary_search_recursive.sf │ ├── binomialmod.sf │ ├── bitonic_sorter.sf │ ├── block_identities.sf │ ├── block_return.sf │ ├── box_the_compass.sf │ ├── break.sf │ ├── built_in_class_reopening.sf │ ├── built_in_classes.sf │ ├── cached_func_method.sf │ ├── caesar_cipher.sf │ ├── calendar.sf │ ├── call_an_object_method.sf │ ├── cartesian.sf │ ├── catalan_numbers.sf │ ├── catalan_numbers_2.sf │ ├── chebyshev_coefficients_test.sf │ ├── chebyshev_factorization_method.sf │ ├── chebyshev_polynomials.sf │ ├── class_attr_inheritance.sf │ ├── class_attributes.sf │ ├── class_field_inheritance.sf │ ├── class_global_variables.sf │ ├── class_has_variables_with_prefix_methods.sf │ ├── class_inheritance.sf │ ├── class_inside_module.sf │ ├── class_redefinition.sf │ ├── class_slurpy_attributes.sf │ ├── class_var_inheritance.sf │ ├── classes.sf │ ├── classes_and_objects.sf │ ├── cnp.sf │ ├── code_interpolation.sf │ ├── combs_and_perms.sf │ ├── complex_numbers.sf │ ├── composites.sf │ ├── compress.sf │ ├── congruence_of_powers_factorization.sf │ ├── const_tests.sf │ ├── constant_folding.sf │ ├── cpp_input_output.sf │ ├── cramers_method.sf │ ├── cramers_rule.sf │ ├── cramers_rule_matrix_class.sf │ ├── cross_and_zip_metaoperators.sf │ ├── cycle_sort.sf │ ├── cyclic_dclone.sf │ ├── cyclic_references_eq_cmp.sf │ ├── data_digging.sf │ ├── data_handle.sf │ ├── date_time.sf │ ├── dec_2016_changes.sf │ ├── def_primitive_type.sf │ ├── def_primitive_type_2.sf │ ├── default_param_values.sf │ ├── default_var_values.sf │ ├── difference_of_powers_factorization.sf │ ├── digits_and_sum_of_digits.sf │ ├── divisor_functions.sf │ ├── divisors_of_factorial_in_range_iterator.sf │ ├── draw_grid_of_squares_multi.sf │ ├── draw_grid_of_squares_multi_2.sf │ ├── dump_cyclic_references.sf │ ├── dynamic_block_scoping.sf │ ├── dynamic_constants.sf │ ├── each_prime.sf │ ├── echo.sf │ ├── enumerator_object.sf │ ├── eq_g2.sf │ ├── equal_classes.sf │ ├── escape_unescape.sf │ ├── euler_and_bernoulli_numbers.sf │ ├── eval.sf │ ├── execute_system_command.sf │ ├── expression_call.sf │ ├── extended_builtin_class.sf │ ├── extreme_floating_point_values.sf │ ├── factorization_methods.sf │ ├── fibonacci_closed_solution.sf │ ├── fibonacci_iterative.sf │ ├── fibonacci_mystery.sf │ ├── filehandles.sf │ ├── find_the_missing_permutation.sf │ ├── first_class_functions_analogously.sf │ ├── floyds_triangle.sf │ ├── for_in_extended.sf │ ├── for_in_range.sf │ ├── for_in_with_user_objects.sf │ ├── for_two_vars.sf │ ├── for_var_in_array.sf │ ├── forward_difference.sf │ ├── fraction_class.sf │ ├── func_scoping.sf │ ├── function_composition.sf │ ├── functional_modules.sf │ ├── functional_style.sf │ ├── gather_take.sf │ ├── gaussian_divisors.sf │ ├── gaussian_integers.sf │ ├── gcd.sf │ ├── get_value_cyclic_references.sf │ ├── getopt.sf │ ├── given_when.sf │ ├── global_variables.sf │ ├── goto.sf │ ├── greatest_subsequential_sum.sf │ ├── group_precedence.sf │ ├── hailstone.sf │ ├── happy_2_years_old.sf │ ├── hash_as_tree.sf │ ├── hash_autovivification.sf │ ├── hash_concat.sf │ ├── hash_from_array.sf │ ├── hash_grep.sf │ ├── hash_selection.sf │ ├── hash_sort.sf │ ├── heap_s_algorithm_iter.sf │ ├── heap_s_algorithm_rec.sf │ ├── horner_s_rule.sf │ ├── hypot.sf │ ├── i_love_you.sf │ ├── iban.sf │ ├── if_elsif_else.sf │ ├── ilog.sf │ ├── implicit_method_call_on_var_.sf │ ├── implicit_numeric_conversions.sf │ ├── infix_methods.sf │ ├── inherited_blocks.sf │ ├── integer_division.sf │ ├── integer_limits.sf │ ├── integers_binary_encoding.sf │ ├── interactive_mode_bug.sf │ ├── inverse_of_factorial.sf │ ├── inverted_syntax.sf │ ├── irootrem.sf │ ├── is_even_perfect.sf │ ├── is_even_perfect_2.sf │ ├── is_power.sf │ ├── is_prime.sf │ ├── karatsuba_multiplication.sf │ ├── lambert_w_and_lgrt.sf │ ├── lazy_iterators.sf │ ├── lazy_iterators_2.sf │ ├── lazy_methods.sf │ ├── leap_year.sf │ ├── lev_fast.sf │ ├── levenshtein_distance.sf │ ├── levenshtein_distance_cached.sf │ ├── lingua_ro.sf │ ├── lingua_ro_numbers.sf │ ├── local_vars.sf │ ├── logic.sf │ ├── long_division.sf │ ├── longest_common_prefix.sf │ ├── longest_common_subsequence.sf │ ├── longest_common_subsequence_2.sf │ ├── loops.sf │ ├── lucas-pocklington_primality_proving.sf │ ├── lucas_sequences.sf │ ├── luhn_test_of_credit_card_numbers.sf │ ├── lvalues.sf │ ├── magic_vars.sf │ ├── man_or_boy.sf │ ├── man_or_boy_2.sf │ ├── man_or_boy_3.sf │ ├── man_or_boy_cached.sf │ ├── math_functions.sf │ ├── matrix_class.sf │ ├── matrix_determinant.sf │ ├── matrix_multiplication.sf │ ├── matrix_operations.sf │ ├── median.sf │ ├── merge_sort.sf │ ├── merge_sort_2.sf │ ├── metaprogramming_2.sf │ ├── metaprogramming_method_definition.sf │ ├── method_aliases.sf │ ├── method_expressions.sf │ ├── miller_rabin_primality_test.sf │ ├── mod_class.sf │ ├── modular_quadratic_formula.sf │ ├── module_access_namespace.sf │ ├── module_definition.sf │ ├── module_identifiers.sf │ ├── module_inclusion.sf │ ├── module_inclusion_2.sf │ ├── module_inclusion_3.sf │ ├── module_loading.sf │ ├── modules_simple_test.sf │ ├── modules_test_1.sf │ ├── modules_test_2.sf │ ├── modulo.sf │ ├── multi_file_edit.sf │ ├── multi_functions.sf │ ├── multi_match_searcher.sf │ ├── multi_methods.sf │ ├── multi_var_assignment.sf │ ├── multiline_expressions.sf │ ├── multiple_dispatch.sf │ ├── multiple_dispatch_builtin_class.sf │ ├── multiple_dispatch_inheritance_1.sf │ ├── multiple_dispatch_inheritance_2.sf │ ├── multiple_dispatch_inheritance_3.sf │ ├── multiplicative_functions.sf │ ├── multisplit.sf │ ├── named_block_arguments.sf │ ├── named_parameters.sf │ ├── names_to_numbers.sf │ ├── nested_classes.sf │ ├── nested_evals.sf │ ├── non_continuous_seq.sf │ ├── nth_number.sf │ ├── nth_prime.sf │ ├── number_binary_search.sf │ ├── number_methods.sf │ ├── object_copy.sf │ ├── object_methods_reflection.sf │ ├── objects_init.sf │ ├── one-dimensional_cellular_automata.sf │ ├── one-dimensional_cellular_automata_2.sf │ ├── open.sf │ ├── pair_namedparam_force_ops.sf │ ├── pairs_test.sf │ ├── palindrome_detection_recursive.sf │ ├── palindromic_numbers.sf │ ├── pascal_matrix_generation.sf │ ├── pcg.sf │ ├── pell_factorization.sf │ ├── perfect_root_power.sf │ ├── perl_eval.sf │ ├── permutations.sf │ ├── permutations_2.sf │ ├── pi_and_e.sf │ ├── pi_machin_like_formula.sf │ ├── pipeline_cross_operator.sf │ ├── pipeline_map_operator.sf │ ├── pipeline_operator.sf │ ├── pipeline_zip_operator.sf │ ├── polymod.sf │ ├── polynomial.sf │ ├── polynomial_regression.sf │ ├── postfix_exclamation_mark.sf │ ├── power_numbers.sf │ ├── powerfree_numbers.sf │ ├── prefix_colon_hash.sf │ ├── prefix_methods.sf │ ├── prefix_unary_operators.sf │ ├── problem_of_apollonius.sf │ ├── pseudoprimes.sf │ ├── pythagorean_means.sf │ ├── quadratic_integers.sf │ ├── quadratic_nonresidue.sf │ ├── quaternion_integers.sf │ ├── quicksort.sf │ ├── quoted_strings.sf │ ├── rand_pick.sf │ ├── random.sf │ ├── range_number.sf │ ├── range_objects.sf │ ├── range_prod.sf │ ├── range_sum.sf │ ├── ranges.sf │ ├── read_a_configuration_file.sf │ ├── rec_reverse.sf │ ├── recursion.sf │ ├── recursive_block_closures.sf │ ├── regex.sf │ ├── regex_bool.sf │ ├── regex_concat.sf │ ├── regex_global_matching.sf │ ├── regex_match_as_array.sf │ ├── regex_pos.sf │ ├── regex_union.sf │ ├── return.sf │ ├── return_types.sf │ ├── reverse_a_base10_integer.sf │ ├── reverse_recursive_general_solution.sf │ ├── roman_numerals_decoding.sf │ ├── roman_numerals_decoding_2.sf │ ├── roman_numerals_decoding_3.sf │ ├── roman_numerals_encoding.sf │ ├── roman_numerals_encoding_2.sf │ ├── root_mean_square.sf │ ├── roots_on_the_rise.sf │ ├── round_half_to_even.sf │ ├── roundf.sf │ ├── run_length_encoding.sf │ ├── run_length_encoding_2.sf │ ├── run_length_encoding_3.sf │ ├── same_fringe.sf │ ├── scalar_context.sf │ ├── script.sf │ ├── selection_sort.sf │ ├── set_any_all.sf │ ├── set_consolidation.sf │ ├── set_operations.sf │ ├── sets_1.sf │ ├── sets_2.sf │ ├── sidef_executor.sf │ ├── sidef_keywords.sf │ ├── sidef_to_json.sf │ ├── sierpinski_alphabet.sf │ ├── sierpinski_carpet.sf │ ├── sierpinski_diamond.sf │ ├── sierpinski_penta.sf │ ├── sierpinski_sidef.sf │ ├── sierpinski_triangle_90.sf │ ├── sierpinski_x.sf │ ├── slices_cons.sf │ ├── slurpy_const.sf │ ├── slurpy_define.sf │ ├── slurpy_static.sf │ ├── smart_match_operator.sf │ ├── smooth_numbers.sf │ ├── smooth_rough.sf │ ├── solve_lcg.sf │ ├── sort_disjoint_sublist.sf │ ├── sort_with_custom_cmp.sf │ ├── soundex.sf │ ├── special_methods.sf │ ├── split_collapse.sf │ ├── sqrtmod_all.sf │ ├── squarefree.sf │ ├── static_const_lazy_init.sf │ ├── string_encodings.sf │ ├── string_escapes.sf │ ├── string_to_number.sf │ ├── strip_chars_from_str.sf │ ├── strip_non_ascii_chars.sf │ ├── structures.sf │ ├── subsets.sf │ ├── subtractive_generator.sf │ ├── sum_and_prod.sf │ ├── sum_of_squares_function.sf │ ├── sum_of_squares_solutions.sf │ ├── sum_remainders.sf │ ├── swap.sf │ ├── sylvesters_sequence.sf │ ├── symbolic_fractions.sf │ ├── symmetric_difference.sf │ ├── sysopen_and_sysread.sf │ ├── tennis_tournament.sf │ ├── ternary_operator.sf │ ├── token_recursive.sf │ ├── top_rank_per_group.sf │ ├── topological_sort.sf │ ├── trial_division.sf │ ├── triangle_path.sf │ ├── tribonacci_closed_form.sf │ ├── trigonometric_functions.sf │ ├── trizen_s_pair_numbers.sf │ ├── try_catch.sf │ ├── two_dimensional_array.sf │ ├── type_comparisons.sf │ ├── typed_parameters.sf │ ├── unary_inc_dec.sf │ ├── unexecuted_arguments.sf │ ├── unicode.sf │ ├── unicode_support.sf │ ├── unicode_whitespaces.sf │ ├── url_encoding_decoding.sf │ ├── var_ref.sf │ ├── var_scoping.sf │ ├── variable_length_run_encoding.sf │ ├── variable_references.sf │ ├── vector.sf │ ├── vigenere_cipher.sf │ ├── while_loop.sf │ ├── wireworld.sf │ ├── with_orwith_else.sf │ ├── with_statement.sf │ ├── word_processing.sf │ ├── word_roots.sf │ └── word_wrap_enumerator.sf ├── WWW │ ├── DNS_query.sf │ ├── deranged_anagrams.sf │ ├── http_tiny.sf │ ├── lwp_module.sf │ ├── rc_rank_languages_by_popularity.sf │ ├── socket.sf │ └── socket_inet.sf ├── absolute_string.sf ├── abstract_type.sf ├── accumulator_factory.sf ├── accumulator_factory_oo.sf ├── ackermann_function.sf ├── add_a_variable_to_a_class_instance_at_runtime.sf ├── aks_test_for_primes.sf ├── align_columns.sf ├── arithmetic_coding.sf ├── bernoulli_numbers.sf ├── bernoulli_numbers_recursive.sf ├── bernoulli_numbers_seidel.sf ├── cached_zeta_function.sf ├── caesar_cipher.sf ├── chebyshev_coefficients.sf ├── chinese_remainder_theorem.sf ├── comb_sort.sf ├── combinations.sf ├── combinations_and_permutations.sf ├── combinations_with_repetitions.sf ├── continued_fraction.sf ├── currying.sf ├── draw_a_cuboid.sf ├── draw_a_cuboid_2.sf ├── draw_grid_of_squares.sf ├── elementary_cellular_automaton.sf ├── elementary_cellular_automaton_regex.sf ├── ethiopian_multiplication.sf ├── extend_your_language.sf ├── fast_fourier_transform.sf ├── faulhaber_s_formula.sf ├── fibonacci_sequence.sf ├── fibonacci_word_fractal.sf ├── first-class_functions.sf ├── functional_summation_of_fractions.sf ├── happy_numbers.sf ├── huffman_coding.sf ├── inheritance_and_subset.sf ├── jaro_distance.sf ├── jensen_s_device_sf ├── josephus_problem.sf ├── json.sf ├── knuth_shuffle.sf ├── lanczos_approximation.sf ├── langton_s_ant.sf ├── langton_s_ant_2.sf ├── linear_congruential_generator.sf ├── mandelbrot_set.sf ├── mersenne_twister.sf ├── multiple_dispatch.sf ├── mutual_recursion.sf ├── path_sum_two_ways.sf ├── permutations_iter.sf ├── permutations_rec.sf ├── pythagorean_means.sf ├── rejection_sampling.sf ├── reverse_the_gender_of_a_string.sf ├── rsa_code.sf ├── sets.sf ├── sidef_from_sidef_logo.sf ├── sidef_from_sidef_logo_2.sf ├── sidef_from_symbols.sf ├── sierpinski_carpet.sf ├── sierpinski_triangle.sf ├── simple_moving_average.sf ├── simple_moving_average_oo.sf ├── smart_word_wrap.sf ├── smart_word_wrap_simple.sf ├── space_collisions.sf ├── stern-brocot_sequence.sf ├── symmetric_summation_of_fractions.sf ├── towers_of_hanoi.sf ├── tree_traversal.sf ├── unique_prefixes.sf ├── variadic_function.sf ├── vector.sf ├── vector_products.sf ├── vigenere_cipher.sf ├── virtual_machine.sf ├── visualize_tree.sf ├── walk_a_dir_recursively.sf ├── xiaolin_wu_s_line_algorithm.sf ├── y_combinator.sf └── zeta_2n.sf ├── t ├── 00-load.t ├── 01-number.t ├── 02-pow.t ├── 03-mod.t ├── 04-inf_nan.t ├── 05-trigonometry.t ├── accumulator_factory.t ├── accumulator_factory_oo.t ├── ackermann_function.t ├── bernoulli_numbers_rec.t ├── best_shuffle.t ├── currying.t ├── eval.t ├── factors_of_a_mersenne.t ├── fast_fourier_transform.t ├── fibonacci.t ├── levenshtein_distance.t ├── man_or_boy.t ├── md5.t ├── oo_inheritance.t ├── pod.t └── smart_word_wrap.t └── utils ├── Concepts ├── sidef_concept.jl ├── sidef_concept.pl ├── sidef_executor.jl ├── sidef_executor.lua └── sidef_executor.pl6 ├── Examples ├── sidef_in_perl.pl └── sidef_parsing.pl ├── Experiments ├── C-inline-function-call.pl ├── operator_precendece.pl ├── regexp_grammars_op_precedence.pl └── regexp_grammars_parser.pl ├── Web interface ├── css │ └── main.css ├── index.cgi ├── index.fcgi └── js │ ├── jquery-3.6.0.min.js │ ├── main.js │ └── tabby.js ├── auto_perltidy.sh ├── bak_cleaner.sh ├── find_class_typos.pl ├── find_invalid_types.pl ├── find_undefined_methods.pl ├── gource-video.sh ├── grep_errors.sh ├── pod_generator.pl ├── sidef2bin.sh ├── sidef2exe.txt ├── test_deparser.pl └── test_parser.pl /.gitignore: -------------------------------------------------------------------------------- 1 | !Build/ 2 | .last_cover_stats 3 | /META.yml 4 | /META.json 5 | /MYMETA.* 6 | *.o 7 | *.pm.tdy 8 | *.bs 9 | 10 | # Devel::Cover 11 | cover_db/ 12 | 13 | # Devel::NYTProf 14 | nytprof.out 15 | 16 | # Dizt::Zilla 17 | /.build/ 18 | 19 | # Module::Build 20 | _build/ 21 | Build 22 | Build.bat 23 | 24 | # Module::Install 25 | inc/ 26 | 27 | # ExtUtils::MakeMaker 28 | /blib/ 29 | /_eumm/ 30 | /*.gz 31 | /Makefile 32 | /Makefile.old 33 | /MANIFEST.bak 34 | /pm_to_blib 35 | /*.zip 36 | 37 | # PDF files 38 | /sidef-number-class-documentation.pdf 39 | /sidef-number-theory.pdf 40 | /sidef-tutorial.pdf 41 | /sidef-book.pdf 42 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for Sidef 2 | 3 | 0.01 2013-30-03 4 | First version, released on an unsuspecting world. 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /lib/Sidef/Object/LazyMethod.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Object::LazyMethod 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = LazyMethod(...) 15 | 16 | 17 | =head1 INHERITS 18 | 19 | Inherits methods from: 20 | 21 | * Sidef::Object::Object 22 | 23 | =head1 METHODS 24 | 25 | =head2 method 26 | 27 | self.method(method, *args) 28 | 29 | Returns the 30 | 31 | =cut 32 | 33 | =head2 new 34 | 35 | self.new 36 | 37 | Returns the 38 | 39 | =cut 40 | -------------------------------------------------------------------------------- /lib/Sidef/Sys/Sig.pm: -------------------------------------------------------------------------------- 1 | package Sidef::Sys::Sig { 2 | 3 | use utf8; 4 | use 5.016; 5 | 6 | sub new { 7 | bless {}, __PACKAGE__; 8 | } 9 | 10 | { 11 | no strict 'refs'; 12 | foreach my $key (keys(%SIG), '__WARN__', '__DIE__') { 13 | *{__PACKAGE__ . '::' . $key} = sub { 14 | my (undef, $signal) = @_; 15 | 16 | if (ref $signal) { 17 | return $SIG{$key} = $signal->get_value; 18 | } 19 | 20 | $SIG{$key}; 21 | }; 22 | } 23 | } 24 | 25 | }; 26 | 27 | 1 28 | -------------------------------------------------------------------------------- /lib/Sidef/Sys/Sig.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Sys::Sig 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = Sig(...) 15 | 16 | =head1 METHODS 17 | 18 | =head2 new 19 | 20 | Sig.new 21 | 22 | Returns the 23 | 24 | =cut 25 | -------------------------------------------------------------------------------- /lib/Sidef/Types/Block/Fork.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Types::Block::Fork 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = Fork(...) 15 | 16 | =head1 METHODS 17 | 18 | =head2 get 19 | 20 | self.get 21 | 22 | Returns the 23 | 24 | Aliases: I, I 25 | 26 | =cut 27 | 28 | =head2 kill 29 | 30 | self.kill(signal) 31 | 32 | Returns the 33 | 34 | =cut 35 | 36 | =head2 new 37 | 38 | self.new 39 | 40 | Returns the 41 | 42 | =cut 43 | -------------------------------------------------------------------------------- /lib/Sidef/Types/Block/Try.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Types::Block::Try 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = Try(...) 15 | 16 | =head1 METHODS 17 | 18 | =head2 catch 19 | 20 | self.catch(block) 21 | 22 | Returns the 23 | 24 | =cut 25 | 26 | =head2 try 27 | 28 | self.try(block) 29 | 30 | Returns the 31 | 32 | =cut 33 | -------------------------------------------------------------------------------- /lib/Sidef/Types/Null/Null.pm: -------------------------------------------------------------------------------- 1 | package Sidef::Types::Null::Null { 2 | 3 | use utf8; 4 | use 5.016; 5 | 6 | use overload 7 | q{bool} => sub { }, 8 | q{0+} => sub { 0 }, 9 | q{""} => sub { '' }; 10 | 11 | use parent qw(Sidef::Object::Object); 12 | 13 | sub new { 14 | bless \(my $nil = undef), __PACKAGE__; 15 | } 16 | 17 | *call = \&new; 18 | 19 | sub get_value { 20 | undef; 21 | } 22 | 23 | sub dump { 24 | Sidef::Types::String::String->new('null'); 25 | } 26 | 27 | *to_s = \&dump; 28 | *to_str = \&dump; 29 | }; 30 | 31 | 1 32 | -------------------------------------------------------------------------------- /lib/Sidef/Types/Null/Null.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Types::Null::Null 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = Null(...) 15 | 16 | 17 | =head1 INHERITS 18 | 19 | Inherits methods from: 20 | 21 | * Sidef::Object::Object 22 | 23 | =head1 METHODS 24 | 25 | =head2 new 26 | 27 | self.new 28 | 29 | Returns the 30 | 31 | Aliases: I 32 | 33 | =cut 34 | 35 | =head2 to_s 36 | 37 | self.to_s 38 | 39 | Returns the 40 | 41 | Aliases: I, I 42 | 43 | =cut 44 | -------------------------------------------------------------------------------- /lib/Sidef/Types/Number/Complex.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Types::Number::Complex 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = Complex(...) 15 | 16 | 17 | =head1 INHERITS 18 | 19 | Inherits methods from: 20 | 21 | * Sidef::Types::Number::Number 22 | 23 | =head1 METHODS 24 | 25 | =head2 new 26 | 27 | self.new 28 | 29 | Returns the 30 | 31 | Aliases: I 32 | 33 | =cut 34 | -------------------------------------------------------------------------------- /lib/Sidef/Variable/GetOpt.pod: -------------------------------------------------------------------------------- 1 | 2 | =encoding utf8 3 | 4 | =head1 NAME 5 | 6 | Sidef::Variable::GetOpt 7 | 8 | =head1 DESCRIPTION 9 | 10 | This class implements ... 11 | 12 | =head1 SYNOPSIS 13 | 14 | var obj = GetOpt(...) 15 | 16 | =head1 METHODS 17 | 18 | =head2 new 19 | 20 | self.new 21 | 22 | Returns the 23 | 24 | =cut 25 | -------------------------------------------------------------------------------- /scripts/Expensive/benford_s_law.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Benford's_law#Perl 4 | 5 | var (actuals, expected) = ([], []) 6 | var fibonacci = 1000.of {|i| fib(i).digit(-1) } 7 | 8 | for i in (1..9) { 9 | var num = fibonacci.count { |j| j == i } 10 | actuals.append(num / 1000) 11 | expected.append(1 + (1/i) -> log10) 12 | } 13 | 14 | "%17s%17s\n".printf("Observed","Expected") 15 | 16 | for i in (1..9) { 17 | "%d : %11s %%%15s %%\n".printf( 18 | i, "%.2f".sprintf(100 * actuals[i-1]), 19 | "%.2f".sprintf(100 * expected[i-1]), 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /scripts/Expensive/closed_form_fibonacci.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func fib_cf(n) { 4 | 5 | define S = sqrt(5); 6 | define T = ((1+S) / 2); 7 | define U = (2 / (1+S)); 8 | 9 | (T**n - (U**n * cos(Num.pi(2*n) * n))) / S -> round(0); 10 | } 11 | 12 | func fib_rec(n) is cached { 13 | n > 1 ? (__FUNC__(n-1) + __FUNC__(n-2)) : n; 14 | } 15 | 16 | range(10, 20).each { |i| 17 | var f = fib_cf(i); 18 | say "F(#{i}) = #{f}"; 19 | assert_eq(f, fib_rec(i)); 20 | } 21 | -------------------------------------------------------------------------------- /scripts/Expensive/concurrent_computing.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Concurrent_computing 5 | # 6 | 7 | \ 8 | -> map{|str| {say str}.fork } \ 9 | -> map{|thr| thr.wait } 10 | -------------------------------------------------------------------------------- /scripts/Expensive/fork.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fork 5 | # 6 | 7 | var x = 42; 8 | var child = { x += 1 }.ffork; 9 | say child.wait; # prints: 43 10 | say x; # but x is still 42 11 | -------------------------------------------------------------------------------- /scripts/Expensive/julia_set.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Julia_set 5 | # 6 | 7 | var (w, h) = (80, 30) 8 | 9 | var maxIter = 40 10 | var c = Complex(-0.8, 0.156) 11 | 12 | for y in ^h { 13 | for x in ^w { 14 | var i = maxIter 15 | var z = Complex(3 * (x - w/2) / w, 2 * (y - h/2) / h) 16 | while (z.abs < 2 && --i) { 17 | z = (z*z + c) 18 | } 19 | print (i > 0 ? ' ' : '#') 20 | } 21 | print "\n" 22 | } 23 | -------------------------------------------------------------------------------- /scripts/Expensive/quicksort_in_parallel.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## The quicksort algorithm in parallel 5 | # 6 | 7 | func quicksort(arr {.len <= 1}) { arr } 8 | 9 | func quicksort(arr) { 10 | 11 | var p = arr.pop_rand; 12 | 13 | var forks = [ 14 | quicksort.ffork(arr.grep { _ <= p }), 15 | quicksort.ffork(arr.grep { _ > p }), 16 | ]; 17 | 18 | forks[0].wait + [p] + forks[1].wait 19 | } 20 | 21 | say quicksort(@(1..50) -> shuffle); 22 | -------------------------------------------------------------------------------- /scripts/Expensive/root_of_a_function.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Roots_of_a_function 4 | 5 | func f(x) { 6 | x*x*x - 3*x*x + 2*x; 7 | } 8 | 9 | var step = 0.001; 10 | var start = -1; 11 | var stop = 3; 12 | 13 | range(start+step, stop, step).each { |x| 14 | static sign = false; 15 | var value = f(x); 16 | given (value) { 17 | when (0) { 18 | say "Root found at #{x}"; 19 | } 20 | case (sign && ((value > 0) != sign)) { 21 | say "Root found near #{x}"; 22 | } 23 | } 24 | sign = value>0; 25 | } 26 | -------------------------------------------------------------------------------- /scripts/Extended tests/digits2num.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use 5.014; 4 | use strict; 5 | use warnings; 6 | 7 | use ntheory qw(:all); 8 | 9 | use lib qw(../../lib); 10 | use Math::Sidef qw(digits digits2num); 11 | 12 | foreach my $B(2..1000) { 13 | 14 | my $N = factorial($B); 15 | my @d = digits($N, $B); 16 | my $M = digits2num($B, \@d); 17 | #my $M = fromdigits([reverse @d], $B); 18 | 19 | if ($M != $N) { 20 | die "Error for N = $N (got $M)"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/Extended tests/prime_bounds.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func f(n) { 4 | 5 | var pi = n.pi 6 | var prime = n.prime 7 | 8 | say "Testing: n = #{n} : #{n.prime_lower} <= #{prime} <= #{n.prime_upper}" 9 | 10 | assert(n.prime_count_lower <= pi) 11 | assert(n.prime_count_upper >= pi) 12 | 13 | assert(n.nth_prime_lower <= prime) 14 | assert(n.nth_prime_upper >= prime) 15 | } 16 | 17 | for k in (1..100) { 18 | f((Num(Num.INTSIZE) <= 32 ? 2e8 : 1e9).irand) 19 | f(k) 20 | } 21 | -------------------------------------------------------------------------------- /scripts/Extended tests/prime_count.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require('ntheory') 4 | 5 | #irand(1234) 6 | 7 | for n in (1..100) { 8 | var k = irand(1e7) 9 | var t = irand(1e6) 10 | 11 | if (t < k) { 12 | (t, k) = (k, t) 13 | } 14 | 15 | var p = k.prime_count(t) 16 | var q = %S.prime_count(k, t) 17 | 18 | say "Testing pi(#{k}, #{t}) = #{p}" 19 | 20 | if (p != q) { 21 | die "Error for k=#{k} t=#{t} -> got #{p} instead of #{q}" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/Extended tests/range_sum.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for n in (1..100) { 4 | 5 | var step = (irand(-100, 100) / irand(1, 100)) 6 | var from = (irand(-1e3, 1e3) / irand(1, 1e2)) 7 | var to = (irand(-1e4, 1e4) / irand(1, 1e2)) 8 | 9 | step += 1 if (step.is_zero) 10 | 11 | say "Testing sum(#{from.as_rat}, #{to.as_rat}, #{step.as_rat}): #{sum(from .. to `by` step).as_rat}" 12 | 13 | if (sum(from .. to `by` step) != sum(from .. to `by` step, { _ })) { 14 | die "!!!!!!!!!!! error for sum(#{from.as_frac}, #{to.as_frac}, #{step.as_frac})" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/Games/guess_the_number.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Guess_the_number 5 | # 6 | 7 | var n = irand(1, 10) 8 | var msg = 'Guess the number: ' 9 | 10 | while (n != read(msg, Number)) { 11 | msg = 'Wrong! Guess again: ' 12 | } 13 | 14 | say 'Well guessed!' 15 | -------------------------------------------------------------------------------- /scripts/Games/guess_the_number_with_feedback.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Guess_the_number/With_feedback 5 | # 6 | 7 | var number = rand(1..10); 8 | say "Guess the number between 1 and 10"; 9 | 10 | loop { 11 | given(var n = Sys.scanln("> ").to_i) { 12 | when (number) { say "You guessed it."; break } 13 | case (n < number) { say "Too low" } 14 | default { say "Too high" } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/Graphical/hello_world_graphical.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Hello_world/Graphical 5 | # 6 | 7 | var tk = require('Tk'); 8 | var main = 'MainWindow'.to_caller.new; 9 | main.Button( 10 | '-text' => 'Goodbye, World!', 11 | '-command' => 'exit', 12 | ).pack; 13 | tk.MainLoop; 14 | -------------------------------------------------------------------------------- /scripts/Graphical/hello_world_graphical_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Hello_world/Graphical 5 | # 6 | 7 | use('Gtk3 -init') 8 | 9 | var gtk3 = %O'Gtk3' 10 | var window = %O'Gtk3::Window'.new 11 | var label = %O'Gtk3::Label'.new('Goodbye, World!') 12 | 13 | window.set_title('Goodbye, World!') 14 | window.signal_connect(destroy => { gtk3.main_quit }) 15 | 16 | window.add(label) 17 | window.show_all 18 | 19 | gtk3.main 20 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_hilbert_curve.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | a => '-bF+aFa+Fb-', 7 | b => '+aF-bFb-Fa+', 8 | ) 9 | 10 | var lsys = LSystem( 11 | width: 600, 12 | height: 600, 13 | 14 | scale: 1, 15 | xoff: -50, 16 | yoff: -50, 17 | 18 | len: 8, 19 | angle: 90, 20 | color: 'dark green', 21 | ) 22 | 23 | lsys.execute('a', 6, "hilbert_curve.png", rules) 24 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_koch_snowflake.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | F => 'F+F--F+F', 7 | ) 8 | 9 | var lsys = LSystem( 10 | width: 800, 11 | height: 800, 12 | 13 | xoff: -210, 14 | yoff: -90, 15 | 16 | len: 8, 17 | angle: 60, 18 | color: 'dark green', 19 | ) 20 | 21 | lsys.execute('F--F--F', 4, "koch_snowflake.png", rules) 22 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_penrose_tiling.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | a => 'cE++dE----bE[-cE----aE]++', 7 | b => '+cE--dE[---aE--bE]+', 8 | c => '-aE++bE[+++cE++dE]-', 9 | d => '--cE++++aE[+dE++++bE]--bE', 10 | E => '', 11 | ) 12 | 13 | var lsys = LSystem( 14 | width: 1000, 15 | height: 1000, 16 | 17 | scale: 1, 18 | xoff: -500, 19 | yoff: -500, 20 | 21 | len: 40, 22 | angle: 36, 23 | color: 'dark blue', 24 | ) 25 | 26 | lsys.execute('[b]++[b]++[b]++[b]++[b]', 5, "penrose_tiling.png", rules) 27 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_plant_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | S => 'T-[[S]+S]+T[+TS]-S', 7 | T => 'TT', # or: 'T[S]T' 8 | ); 9 | 10 | var lsys = LSystem( 11 | width: 1000, 12 | height: 1000, 13 | 14 | scale: 0.7f, 15 | xoff: -200, 16 | yoff: 300, 17 | 18 | len: 8, 19 | angle: 25, 20 | color: 'dark green', 21 | ); 22 | 23 | lsys.execute('S', 6, "plant_1.png", rules); 24 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_plant_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | S => 'SS+[+S-S-S]-[-S+S+S]' 7 | ); 8 | 9 | var lsys = LSystem( 10 | width: 1000, 11 | height: 1000, 12 | 13 | xoff: -600, 14 | 15 | len: 8, 16 | angle: 25, 17 | color: 'dark green', 18 | ); 19 | 20 | lsys.execute('S', 5, "plant_2.png", rules); 21 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_sierpinski_triangle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | S => 'S--S--S--T', 7 | T => 'TT', 8 | ); 9 | 10 | var lsys = LSystem( 11 | width: 1000, 12 | height: 1000, 13 | 14 | scale: 0.4, 15 | xoff: -280, 16 | yoff: 400, 17 | 18 | len: 30, 19 | angle: 120, 20 | turn: 30, 21 | color: 'dark red', 22 | ); 23 | 24 | lsys.execute('S--S--S', 7, "sierpinksi_triangle.png", rules); 25 | -------------------------------------------------------------------------------- /scripts/Graphical/lsystem_tree.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include('LSystem/LSystem.sf') 4 | 5 | var rules = Hash( 6 | S => 'T[-S]+S', 7 | T => 'TT', 8 | ); 9 | 10 | var lsys = LSystem( 11 | width: 1000, 12 | height: 1000, 13 | 14 | scale: 0.4, 15 | xoff: 100, 16 | yoff: 700, 17 | 18 | len: 5, 19 | angle: 35, 20 | color: 'dark green', 21 | ); 22 | 23 | lsys.execute('S', 9, "tree.png", rules); 24 | -------------------------------------------------------------------------------- /scripts/Graphical/munching_squares.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Munching_squares 5 | # 6 | 7 | require('GD'); 8 |   9 | var img = %O'GD::Image'.new(256, 256, 1); 10 | 11 | var r = 0..255; 12 | 13 | for y=r, x=r { 14 | var color = img.colorAllocate((255 - x - y).abs, (255-x)^y, x^(255-y)); 15 | img.setPixel(x, y, color); 16 | } 17 |   18 | if (var fh = %f(xor.png).open('>:raw')) { 19 | fh << img.png; 20 | } 21 | -------------------------------------------------------------------------------- /scripts/Graphical/window_creation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Window_creation 5 | # 6 | 7 | var tk = require('Tk'); 8 | 'MainWindow'.to_caller.new; 9 | tk.MainLoop; 10 | -------------------------------------------------------------------------------- /scripts/Graphical/window_creation_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Window_creation 5 | # 6 | 7 | use('Gtk3 -init') 8 | var gtk3 = %O'Gtk3' 9 | var window = %O'Gtk3::Window'.new; 10 | window.signal_connect(destroy => func(_) { gtk3.main_quit }); 11 | window.show_all; 12 | gtk3.main; 13 | -------------------------------------------------------------------------------- /scripts/Interactive/integer_comparison.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Integer_comparison 5 | # 6 | 7 | var a = read("a: ", Number); 8 | var b = read("b: ", Number); 9 |   10 | if (a < b) { 11 | say 'Lower'; 12 | } 13 | elsif (a == b) { 14 | say 'Equal'; 15 | } 16 | elsif (a > b) { 17 | say 'Greater'; 18 | } 19 | -------------------------------------------------------------------------------- /scripts/Interactive/menu.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Menu 5 | # 6 | 7 | func menu (prompt, arr) { 8 | arr.len > 0 || return ''; 9 | loop { 10 | arr.range.each { |i| 11 | say " #{i}: #{arr[i]}"; 12 | }; 13 | var n = Sys.scanln(prompt); 14 | n ~~ /^[0-9]+\z/ ? n.to_i! : next; 15 | arr.exists(n) && return arr[n]; 16 | } 17 | } 18 |   19 | var list = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']; 20 | var prompt = 'Please choose an item number: '; 21 |   22 | var answer = menu(prompt, list); 23 | say "You choose: #{answer}"; 24 | -------------------------------------------------------------------------------- /scripts/Interactive/sparkline_in_unicode.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sparkline_in_unicode 5 | # 6 | 7 | var bar = @('▁'..'█'); 8 | loop { 9 | print 'Numbers, please, separated by space/commas: '; 10 | var numbers = read(String).trim.split(/[\s,]+/).map{.to_f}; 11 | var (min, max) = numbers.minmax; 12 | say "min: %5f; max: %5f"%(min, max); 13 | var div = ((max - min) / bar.end); 14 | say (min == max ? bar.last*numbers.len : numbers.map{|num| bar[(num - min) / div]}.join); 15 | } 16 | -------------------------------------------------------------------------------- /scripts/Interactive/temperature_conversion.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var scale = Hash.new( 4 | Celcius => Hash.new(factor => 1 , offset => -273.15 ), 5 | Rankine => Hash.new(factor => 1.8, offset => 0 ), 6 | Fahrenheit => Hash.new(factor => 1.8, offset => -459.67 ), 7 | ); 8 | 9 | var kelvin = Sys.readln("Enter a temperature in Kelvin: ").to_num; 10 | kelvin >= 0 || die "No such temperature!"; 11 | 12 | scale.keys.sort.each { |key| 13 | printf("%12s:%8.2f\n", key, kelvin*scale{key}{:factor} + scale{key}{:offset}); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/Interactive/user_input_text.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/User_input/Text 5 | # 6 | 7 | var s = read("string: ", String); 8 | var i = read("number: ", Number); # auto-conversion to a number 9 | 10 | say s; 11 | say i; 12 | -------------------------------------------------------------------------------- /scripts/Interactive/user_input_text_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/User_input/Text 5 | # 6 | 7 | var s = Sys.readln("Enter a string: "); 8 | var i = Sys.readln("Enter a number: ").to_i; 9 | 10 | say s; 11 | say i; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/almost_prime.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Almost_prime#Sidef 5 | # 6 | 7 | func is_k_almost_prime(n, k) { 8 | for (var (p, f) = (2, 0); (f < k) && (p*p <= n); ++p) { 9 | (n /= p; ++f) while (n %% p); 10 | } 11 | f + (n > 1 ? 1 : 0) == k 12 | } 13 | 14 | for k in (1..5) { 15 | var x = 10 16 | say gather { 17 | for i in (1 .. Inf) { 18 | if (is_k_almost_prime(i, k)) { 19 | take(i); (--x).is_zero && break; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/RosettaCode/arithmetic-geometric_mean.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Arithmetic-geometric_mean 5 | # 6 | 7 | func agm(a, g) { 8 | loop { 9 | var x = [(a+g) / 2, sqrt(a*g)]; 10 | x == [a, g] && return a; 11 | (a, g) = x...; 12 | } 13 | } 14 |   15 | say agm(1, 1/sqrt(2)); 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/averages_arithmetic_mean.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Averages/Arithmetic_mean 5 | # 6 | 7 | func avg(list) { 8 | list.is_a(Array) || return nil; 9 | list.len > 0 || return 0; 10 | list.sum / list.len; 11 | } 12 |   13 | say avg([Inf, Inf]); 14 | say avg([3,1,4,1,5,9]); 15 | say avg([1e+20, 3, 1, 4, 1, 5, 9, -1e+20]); 16 | say avg([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0.11]); 17 | say avg([10, 20, 30, 40, 50, -100, 4.7, -1100]); 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/averages_mode.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Averages/Mode 5 | # 6 | 7 | func mode(array) { 8 | var c = Hash.new; 9 | array.each{|i| c{i} := 0 ++}; 10 | var max = c.values.max; 11 | c.keys.grep{|i| c{i} == max}; 12 | } 13 | 14 | say mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]).join(' '); 15 | say mode([1, 1, 2, 4, 4]).join(' '); 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/averages_mode_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Averages/Mode 5 | # 6 | 7 | func one_mode(arr) { 8 | arr.max_by{|i| arr.count(i)}; 9 | } 10 | 11 | say one_mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]); 12 | say one_mode([1, 1, 2, 4, 4]); 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/averages_pythagorean_means.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Averages/Pythagorean_means 5 | # 6 | 7 | func A(a) { a.sum / a.len }; 8 | func G(a) { a.prod.root(a.len) }; 9 | func H(a) { a.len / a.map{.inv}.sum }; 10 |   11 | say("A(1,...,10) = ", A(1..10)); 12 | say("G(1,...,10) = ", G(1..10)); 13 | say("H(1,...,10) = ", H(1..10)); 14 | 15 | assert_eq(Math.arithmetic_mean(1..10 -> ...), A(1..10)) 16 | assert_eq(Math.geometric_mean(1..10 -> ...), G(1..10)) 17 | assert_eq(Math.harmonic_mean(1..10 -> ...), H(1..10)) 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/averages_root_mean_square.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Averages/Root_mean_square 5 | # 6 | 7 | func rms(a) { 8 | sqrt(a.map{.**2}.sum / a.len); 9 | } 10 |   11 | say rms(1..10); 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/binary_digits.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Binary_digits 5 | # 6 | 7 | [5, 50, 9000].each { |n| 8 | say n.as_bin; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/binary_search.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Binary_search 5 | # 6 | 7 | func binary_search(a, i) { 8 |   9 | var l = 0; 10 | var h = a.end; 11 |   12 | while (l <= h) { 13 | var mid = (h+l / 2 -> int); 14 | a[mid] > i && (h = mid-1; next); 15 | a[mid] < i && (l = mid+1; next); 16 | return mid; 17 | } 18 |   19 | return -1; 20 | } 21 | 22 | say binary_search(@(1..100), 23); 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/binary_search_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Binary_search 5 | # 6 | 7 | func binary_search(array, value, low, high) { 8 | high < low && return -1; 9 | var middle = (high+low / 2 -> int); 10 |   11 | if (value < array[middle]) { 12 | return binary_search(array, value, low, middle-1); 13 | } 14 | elsif (value > array[middle]) { 15 | return binary_search(array, value, middle+1, high); 16 | } 17 |   18 | return middle; 19 | } 20 | 21 | say binary_search(@(1..100), 23, 0, 99); 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/bitwise_operations.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Bitwise_operations 5 | # 6 | 7 | func bitwise(a, b) { 8 |   9 | # Make sure they are integers 10 | a.to_int!; 11 | b.to_int!; 12 |   13 | say ('a and b : ', a & b); 14 | say ('a or b  : ', a | b); 15 | say ('a xor b : ', a ^ b); 16 | say ('not a  : ', ~a); 17 | say ('a << b  : ', a << b); # left shift 18 | say ('a >> b  : ', a >> b); # arithmetic right shift 19 | } 20 |   21 | bitwise(14,3) 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/boolean_values.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Boolean_values 5 | # 6 | 7 | var t = true; 8 | var f = false; 9 | 10 | say t; 11 | say f; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/boolean_values_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Boolean_values 5 | # 6 | 7 | if (0 || "0" || false || nil || "" || [] || :()) { 8 | say "true" 9 | } else { 10 | say "false"; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/case-sensitivity_of_identifiers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Case-sensitivity_of_identifiers 5 | # 6 | 7 | var dog = 'Benjamin'; 8 | var Dog = 'Samba'; 9 | var DOG = 'Bernie'; 10 | say "The three dogs are named #{dog}, #{Dog}, and #{DOG}."; 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/catalan_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Catalan_numbers 5 | # 6 | 7 | func f(i) { i==0 ? 1 : (i * f(i-1)) }; 8 | func c(n) { f(2*n) / f(n) / f(n+1) }; 9 | 10 | for i in (0..15) { 11 | say "#{i}\t#{c(i)}"; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/catalan_numbers_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Catalan_numbers 5 | # 6 | 7 | var mem = [1] 8 | func c(n) { 9 | mem[n-1] := (c(n-1) * (4 * n - 2) / (n + 1)) 10 | } 11 | 12 | for i in (0..15) { 13 | say "#{i}\t#{c(i)}" 14 | } 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/catalan_numbers_pascal_triangle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Catalan_numbers/Pascal%27s_triangle 5 | # 6 | 7 | func catalan(num) { 8 | var t = [0, 1]; 9 | range(1, num).map { |i| 10 | range(i, 1, -1).each {|j| t[j] += t[j-1]}; 11 | t[i+1] = t[i]; 12 | range(i+1, 1, -1).each {|j| t[j] += t[j-1]}; 13 | t[i+1] - t[i]; 14 | } 15 | } 16 | 17 | say catalan(15).join(' '); 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/catamorphism.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Catamorphism 5 | # 6 | 7 | say (1..10 -> reduce('+')); 8 | say (1..10 -> reduce{|a,b| a + b}); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/character_codes.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Character_codes 5 | # 6 | 7 | say 'a'.ord; # => 97 8 | say 97.chr; # => 'a' (of type Char) 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/check_that_file_exists.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Check_that_file_exists 5 | # 6 | 7 | # Here 8 | say (Dir.cwd + %f'input.txt' -> is_file); 9 | say (Dir.cwd + %d'docs' -> is_dir); 10 |   11 | # Root 12 | say (Dir.root + %f'input.txt' -> is_file); 13 | say (Dir.root + %d'docs' -> is_dir); 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/classes.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Classes 5 | # 6 | 7 | class MyClass(instance_var=1) { 8 | method add(Number num) { 9 | instance_var += num; 10 | } 11 | } 12 |   13 | var obj = MyClass(3); # `instance_var` will be set to 3 14 | obj.add(5); # calls the add() method 15 | say obj.instance_var; # prints the value of `instance_var`: 8 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/closures_value_capture.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Closures/Value_capture 5 | # 6 | 7 | var f = ( 8 | 0..9 -> map {|i| func(j){i * j} } 9 | ); 10 |   11 | 0 ..^ 8 -> each { |j| 12 | say f[j].call(j); 13 | }; 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/compare_a_list_of_strings.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Compare_a_list_of_strings 5 | # 6 | 7 | var arr = [1,2,3,4,5]; 8 | 9 | say (1..arr.end -> all{ arr[0] == arr[_] }); # All equal 10 | say (1..arr.end -> all{ arr[_-1] < arr[_] }); # Strictly ascending 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/compare_a_list_of_strings_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Compare_a_list_of_strings 5 | # 6 | 7 | var arr = [1,2,3,4,5]; 8 | 9 | say (arr.unique.len == 1); # all equal? 10 | say (arr == arr.sort); # sorted? 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/compile-time_calculation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Compile-time_calculation 5 | # 6 | 7 | define n = 10!; 8 | say n; 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/compile-time_calculation_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Compile-time_calculation 5 | # 6 | 7 | define n = (func(n){ n > 0 ? __FUNC__(n-1)*n : 1 }(10)); 8 | say n; 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/compound_data_type.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Compound_data_type 5 | # 6 | 7 | class Point(x, y) {}; 8 | var point = Point(1, 2); 9 | say point.y; #=> 2 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/convert_decimal_number_to_rational.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Convert_decimal_number_to_rational 5 | # 6 | 7 | '0.9054054 0.518518 0.75'.split.each { |d| 8 | say Num(d) 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/copy_a_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Copy_a_string 5 | # 6 | 7 | var original = "hello"; # new String object 8 | var reference = original; # points at the original object 9 | var copy1 = String.new(original); # creates a new String object 10 | var copy2 = original+''; # ==//== 11 | 12 | say reference; 13 | say copy1; 14 | say copy2; 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/count_occurrences_of_a_substring.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Count_occurrences_of_a_substring 5 | # 6 | 7 | say "the three truths".count("th"); 8 | say "ababababab".count("abab"); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/count_the_coins.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Count_the_coins 5 | # 6 | 7 | func cc(_) { 0 } 8 | func cc({ .is_neg }, *_) { 0 } 9 | func cc({ .is_zero }, *_) { 1 } 10 | 11 | func cc(amount, first, *rest) is cached { 12 | cc(amount, rest...) + cc(amount - first, first, rest...); 13 | } 14 | 15 | func cc_optimized(amount, *rest) { 16 | cc(amount, rest.sort_by{|v| -v }...); 17 | } 18 | 19 | var x = cc_optimized(100, 1, 5, 10, 25); 20 | say "Ways to change $1 with common coins: #{x}"; 21 | 22 | assert_eq(x, 242); 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/cumulative_standard_deviation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Cumulative_standard_deviation 5 | # 6 | 7 | class StdDevAccumulator(n=0, sum=0, sumofsquares=0) { 8 | method <<(num) { 9 | n += 1; 10 | sum += num; 11 | sumofsquares += num**2; 12 | self; 13 | } 14 | 15 | method stddev { 16 | sqrt(sumofsquares/n - pow(sum/n, 2)); 17 | } 18 | 19 | method to_s { 20 | self.stddev.to_s; 21 | } 22 | } 23 | 24 | var i = 0; 25 | var sd = StdDevAccumulator.new; 26 | [2,4,4,4,5,5,7,9].each {|n| 27 | say "adding #{n}: stddev of #{i+=1} samples is #{sd << n}" 28 | } 29 | -------------------------------------------------------------------------------- /scripts/RosettaCode/date_format.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Date_format 5 | # 6 | 7 | var time = Time.local; 8 | say time.ctime; 9 | say time.strftime("%Y-%m-%d"); 10 | say time.strftime("%A, %B %d, %Y"); 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/decimal_float_to_binary.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Decimal_floating_point_number_to_binary 5 | # 6 | 7 | func dec2bin(String n) { 8 | Num(Num(n, 10).base(2), 10) 9 | } 10 | 11 | func bin2dec(String n) { 12 | Num(Num(n, 10).base(10), 2) 13 | } 14 | 15 | with("23.34375") { |s| say (" #{s} => ", dec2bin(s)) } 16 | with("1011.11101") { |s| say ( "#{s} => ", bin2dec(s)) } 17 | 18 | assert_eq(dec2bin("23.34375"), 10111.01011.float) 19 | assert_eq(bin2dec("1011.11101"), 11.90625.float) 20 | -------------------------------------------------------------------------------- /scripts/RosettaCode/delete_a_file.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Delete_a_file 5 | # 6 | 7 | # here 8 | %f'input.txt' -> delete; 9 | %d'docs' -> delete; 10 |   11 | # root dir 12 | Dir.root + %f'input.txt' -> delete; 13 | Dir.root + %d'docs' -> delete; 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/determine_if_a_string_is_numeric.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Determine_if_a_string_is_numeric 5 | # 6 | 7 | func is_numeric(s) { 8 | (s ~~ /^[+-]?+(?=\.?[0-9])[0-9_]*+(?:\.[0-9_]++)?(?:[Ee](?:[+-]?+[0-9_]+))?\z/) || 9 | (s ~~ /^0(?:b[10_]*|x[0-9A-Fa-f_]*|[0-9_]+\b)\z/); 10 | }; 11 | 12 | var strings = %w(0 0.0 -123 abc 0x10 0xABC 123a -123e3 0.1E-5 50e); 13 | strings.each { |str| 14 | say ("%9s => %s" % (str, is_numeric(str))); 15 | }; 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/dot_product.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Dot_product 5 | # 6 | 7 | func dot_product(a, b) { 8 | (a »*« b)«+»; 9 | }; 10 | say dot_product([1,3,-5], [4,-2,-1]); # => 3 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/empty_directory.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Empty_directory 5 | # 6 | 7 | Dir.new('/my/dir').is_empty; # true, false or nil 8 | -------------------------------------------------------------------------------- /scripts/RosettaCode/empty_directory_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Empty_directory 5 | # 6 | 7 | func is_empty(dir) { 8 | dir.open(\var dir_h) || return nil; 9 | dir_h.each { |file| 10 | file ~~ ['.', '..'] && next; 11 | return false; 12 | }; 13 | return true; 14 | }; 15 | 16 | say is_empty(Dir.cwd); 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/entropy.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Entropy 5 | # 6 | 7 | func entropy(s) { 8 | var counts = Hash.new; 9 | s.each { |c| counts{c} := 0 ++ }; 10 | var len = s.len; 11 | [0, counts.values.map {|count| 12 | var freq = count/len; freq * freq.log2 }... 13 | ]«-»; 14 | } 15 |   16 | say entropy("1223334444"); 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/entropy_narcissist.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Entropy/Narcissist 5 | # 6 | 7 | func entropy(s) { 8 | [0, 9 | s.chars.freq.values.map {|c| 10 | var f = c/s.len 11 | f * f.log2 12 | }... 13 | ]«-» 14 | } 15 | 16 | say entropy(File(__FILE__).open_r.slurp) 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/enumerations.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Enumerations 5 | # 6 | 7 | enum {Apple, Banana, Cherry}; # numbered 0 through 2 8 | 9 | say Apple; 10 | say Banana; 11 | say Cherry; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/enumerations_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Enumerations 5 | # 6 | 7 | enum { 8 | Apple=3, 9 | Banana, # gets the value 4 10 | Cherry="a", 11 | Orange, # gets the value "b" 12 | }; 13 | 14 | say Apple; 15 | say Banana; 16 | say Cherry; 17 | say Orange; 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/equilibrium_index.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Equilibrium_index 5 | # 6 | 7 | func eq_index(nums) { 8 | var (i, sum, sums) = (0, 0, Hash.new) 9 | nums.each { |n| 10 | sums{2*sum + n} := [] -> append(i++) 11 | sum += n; 12 | } 13 | sums{sum} \\ []; 14 | }; 15 | 16 | var indices = [ 17 | [-7, 1, 5, 2,-4, 3, 0], 18 | [2, 4, 6], 19 | [2, 9, 2], 20 | [1,-1, 1,-1, 1,-1, 1], 21 | ]; 22 | indices.each { |x| 23 | say ("%s => %s" % [x, eq_index(x)].map{.dump}...); 24 | }; 25 | -------------------------------------------------------------------------------- /scripts/RosettaCode/factorial.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Factorial 5 | # 6 | 7 | # Recursive 8 | func factorial_recursive(n) { 9 | n == 0 ? 1 : (n * __FUNC__(n-1)); 10 | }; 11 |   12 | # Iterative with Array#reduce 13 | func factorial_reduce(n) { 14 | 1..n -> reduce('*'); 15 | }; 16 |   17 | # Iterative with Block#repeat 18 | func factorial_iterative(n) { 19 | var f = 1; 20 | {|i| f *= i } * n; 21 | return f; 22 | }; 23 |   24 | # Built-in Number#factorial: 25 | say 5!; 26 | -------------------------------------------------------------------------------- /scripts/RosettaCode/factors_of_an_integers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Factors_of_an_integer 5 | # 6 | 7 | func factors(n) { 8 | gather { 9 | { |d| 10 | take(d, n//d) if d.divides(n) 11 | } << 1..n.isqrt 12 | }.sort.uniq 13 | } 14 |   15 | for n [53, 64, 32766] { 16 | say "factors(#{n}): #{factors(n)}" 17 | } 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/faulhaber_s_formula_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Faulhaber%27s_formula 5 | # 6 | 7 | func faulhaber_s_formula(p) { 8 | "1/#{p + 1} * (" + gather { 9 | { |j| 10 | take "#{binomial(p+1, j) * j.bernfrac -> as_rat}*n^#{p+1 - j}" 11 | } << 0..p 12 | }.join(' + ') + ")" 13 | } 14 | 15 | { |p| 16 | printf("%2d: %s\n", p, faulhaber_s_formula(p)) 17 | } << ^10 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/fibonacci_n-step_number_sequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fibonacci_n-step_number_sequences 5 | # 6 | 7 | func fib(n, xs=[1]) { 8 | xs.clone!; 9 | 10 | loop { 11 | var len = xs.len; 12 | len >= 20 && break; 13 | xs.append(xs.slice(0 `max` len-n, len).sum); 14 | } 15 | 16 | xs; 17 | } 18 | 19 | range(2, 10).each { |i| 20 | say fib(i).join(' ') 21 | } 22 | say fib(2, [2, 1]).join(' ') 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/fibonacci_sequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fibonacci_sequence 5 | # 6 | 7 | func fib_iter(n) { 8 | var fib = [1, 1]; 9 | (n - fib.len).times { 10 | fib = [fib[-1], fib[-2] + fib[-1]] 11 | }; 12 | return fib[-1]; 13 | } 14 | 15 | say fib_iter(12); 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/fibonacci_sequence_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fibonacci_sequence 5 | # 6 | 7 | func fib_rec(n) { 8 | n < 2 ? n : (__FUNC__(n-1) + __FUNC__(n-2)); 9 | } 10 | 11 | say fib_rec(12); 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/fibonacci_sequence_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fibonacci_sequence 5 | # 6 | 7 | var c = []; 8 | func fib_mem (n) { 9 | n < 2 && return n; 10 | c[n] := (__FUNC__(n-1) + __FUNC__(n-2)); 11 | } 12 | 13 | say fib_mem(35); 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/fibonacci_sequence_3.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Fibonacci_sequence 5 | # 6 | 7 | func fib_closed(n) { 8 | define S = (1.25.sqrt + 0.5); 9 | define T = (-S + 1); 10 | (S**n - T**n) / (-T + S) -> roundf(0); 11 | } 12 | 13 | say fib_closed(12); 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/file_modification_time.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/File_modification_time 5 | # 6 | 7 | var file = File.new(__FILE__); 8 | say file.stat.mtime; # seconds since the epoch 9 |   10 | # keep atime unchanged 11 | # set mtime to current time 12 | file.utime(file.stat.atime, Time.now); 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/file_size.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/File_size 5 | # 6 | 7 | say (Dir.cwd + %f'input.txt' -> size); 8 | say (Dir.root + %f'input.txt' -> size); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/filter.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Filter 5 | # 6 | 7 | var arr = [1,2,3,4,5]; 8 |   9 | # Creates a new array 10 | var new = arr.grep {|i| i %% 2}; 11 | say new.dump; # => [2, 4] 12 |   13 | # Destructive (at variable level) 14 | arr.grep! {|i| i %% 2}; 15 | say arr.dump; # => [2, 4] 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/find_common_directory_path.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Find_common_directory_path#Sidef 5 | # 6 | 7 | var dirs = %w( 8 | /home/user1/tmp/coverage/test 9 | /home/user1/tmp/covert/operator 10 | /home/user1/tmp/coven/members 11 | ); 12 | 13 | var unique_pref = dirs.map{.split('/')}.uniq_prefs.min_by{.len}; 14 | var common_dir = [unique_pref, unique_pref.pop][0].join('/'); 15 | say common_dir; # => /home/user1/tmp 16 | 17 | 18 | assert_eq(common_dir, '/home/user1/tmp'); 19 | -------------------------------------------------------------------------------- /scripts/RosettaCode/first-class_functions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/First-class_functions 5 | # 6 | 7 | func compose(f,g) { 8 | func (*args) { 9 | f(g(args...)) 10 | } 11 | } 12 | 13 | var cube = func(a) { a.pow(3) } 14 | var croot = func(a) { a.root(3) } 15 | 16 | var flist1 = [Num.method(:sin), Num.method(:cos), cube] 17 | var flist2 = [Num.method(:asin), Num.method(:acos), croot] 18 | 19 | for a,b (flist1 ~Z flist2) { 20 | say compose(a, b)(0.5) 21 | } 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/flatten_a_list.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Flatten_a_list 5 | # 6 | 7 | func flatten(a) { 8 | var flat = [] 9 | a.each { |item| 10 | flat << (item.kind_of(Array) ? __FUNC__(item)... : item) 11 | } 12 | return flat 13 | } 14 |   15 | var arr = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []] 16 | say flatten(arr) # used-defined function 17 | say arr.flatten # built-in method for Array obj 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/formatted_numeric_output.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Formatted_numeric_output 5 | # 6 | 7 | printf("%09.3f\n", 7.125); 8 | -------------------------------------------------------------------------------- /scripts/RosettaCode/formatted_numeric_output_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Formatted_numeric_output 5 | # 6 | 7 | say ("%09.3f" % 7.125); 8 | -------------------------------------------------------------------------------- /scripts/RosettaCode/function_composition.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Function_composition 5 | # 6 | 7 | func compose(f, g) { 8 | func(x) { f(g(x)) }; 9 | }; 10 | var fg = compose(func(x){sin(x)}, func(x){cos(x)}); 11 | say fg(0.5); # => 0.7691963548410084218525147580510688880995 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/function_definition.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Function_definition 5 | # 6 | 7 | func multiply(a, b) { 8 | a * b; 9 | }; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/gamma_function_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Gamma_function 5 | # 6 | 7 | define e = Number.e; 8 | define pi = Number.pi; 9 |   10 | func Γ(t) { 11 | t < 20 ? (__FUNC__(t + 1) / t) 12 |  : (sqrt(2*pi*t) * pow(t/e + 1/(12*e*t), t) / t); 13 | } 14 |   15 | (1..10).each { |i| 16 | say ("%.14e" % Γ(i/3)); 17 | }; 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/generate_lower_case_ascii_alphabet.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Generate_lower_case_ASCII_alphabet 5 | # 6 | 7 | var arr = @('a'..'z'); 8 | say arr.join(' '); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/generic_swap.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Generic_swap 5 | # 6 | 7 | func swap(Ref a, Ref b) { 8 | var tmp = *a; 9 | *a = *b; 10 | *b = tmp; 11 | } 12 | 13 | var (x, y) = (1, 2); 14 | swap(\x, \y); 15 | 16 | say x; 17 | say y; 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/generic_swap_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Generic_swap 5 | # 6 | 7 | func swap(Ref a, Ref b) { 8 | (*b, *a) = (*a, *b); 9 | } 10 | 11 | var (x, y) = (1, 2); 12 | swap(\x, \y); 13 | 14 | say x; 15 | say y; 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/get_system_command_output.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Get_system_command_output 5 | # 6 | 7 | var output = `ls`; # `output` is a string 8 | var lines = `ls`.lines; # `lines` is an array 9 | 10 | say output.len; 11 | say lines.len; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/get_system_command_output_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Get_system_command_output 5 | # 6 | 7 | var pipe = %p(ls); # same as: Pipe.new('ls'); 8 | var pipe_h = pipe.open_r; # open the pipe for reading 9 | var lines = []; # will store the lines of the output 10 | pipe_h.each { |line| lines.append(line.chomp) }; 11 | 12 | say lines.len; 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/greatest_common_divisor.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Greatest_common_divisor 5 | # 6 | 7 | var arr = [100, 1_000, 10_000, 20]; 8 | say Math.gcd(arr...); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/greatest_common_divisor_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Greatest_common_divisor 5 | # 6 | 7 | func gcd(a, b) { 8 | b.is_zero ? a.abs : gcd(b, a % b); 9 | } 10 | 11 | say gcd(90, 24); 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/greatest_element_of_a_list.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Greatest_element_of_a_list 5 | # 6 | 7 | var values = [4,5,2,7,1,3,6]; 8 | say values.max; 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/hash_from_two_arrays.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Hash_from_two_arrays 5 | # 6 | 7 | var keys = %w(a b c); 8 | var vals = [1, 2, 3]; 9 |   10 | var hash = Hash() 11 | hash{keys...} = vals... 12 | 13 | say hash; 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/hickerson_series_of_almost_integers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Hickerson_series_of_almost_integers 5 | # 6 | 7 | func h(n) { 8 | n! / (2 * pow(2.log, n+1)); 9 | } 10 |   11 | for n in (1..17) { 12 | var hn = h(n).roundf(-3); 13 | "h(%2d) = %22s is%s almost an integer.\n".printf( 14 | n, hn, hn.to_s ~~ /\.[09]/ ? '' : ' NOT'); 15 | } 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/higher-order_functions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Higher-order_functions 5 | # 6 | 7 | func first(f) { 8 | return f(); 9 | } 10 |   11 | func second { 12 | return "second"; 13 | } 14 |   15 | say first(second); # => "second" 16 | say first(func { "third" }); # => "third" 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/hostname.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Hostname 5 | # 6 | 7 | var sys = frequire('Sys::Hostname'); 8 | var host = sys.hostname; 9 | 10 | say host; 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/identity_matrix.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Identity_matrix 5 | # 6 | 7 | func identity_matrix(n) { 8 | 1..n -> map { |i| 9 | 1..n -> map {|j| j == i ? 1 : 0 } 10 | } 11 | } 12 |   13 | (ARGV.len ? ARGV.map {.to_i} : [4, 5, 6]) -> each { |n| 14 | say "\n#{n}:"; 15 | identity_matrix(n).each { |row| 16 | say row.join(' '); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /scripts/RosettaCode/infinity.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Infinity 5 | # 6 | 7 | var a = 1.5/0; # inf 8 | say a.is_inf; # true 9 | say a.is_pos; # true 10 |   11 | var b = -1.5/0; # -inf 12 | say b.is_ninf; # true 13 | say b.is_neg; # true 14 |   15 | var inf = Inf 16 | var ninf = -Inf; 17 | say (inf == -ninf); # true 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/inheritance_multiple.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Inheritance/Multiple 5 | # 6 | 7 | class Camera {}; 8 | class MobilePhone {}; 9 | class CameraPhone << Camera, MobilePhone {}; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/inheritance_single.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Inheritance/Single 5 | # 6 | 7 | class Animal {}; 8 | class Dog << Animal {}; 9 | class Cat << Animal {}; 10 | class Lab << Dog {}; 11 | class Collie << Dog {}; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/kaprekar_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Kaprekar_numbers 5 | # 6 | 7 | var kap = Hash() 8 | var nt = frequire('ntheory') 9 | 10 | for n in (1..15) { 11 | var np = (10**n - 1) 12 | nt.fordivisors({ |d| 13 | var dp = np//d 14 | if (gcd(d, dp) == 1) { 15 | kap{ dp == 1 ? d : d*invmod(d, dp) } := 0 ++ 16 | } 17 | }, np) 18 | } 19 | 20 | var nums = kap.keys.map{ Num(_) }.sort 21 | 22 | for n in (6 .. 14) { 23 | var np = (10**n - 1) 24 | printf("Kaprekar numbers <= 10^%2d: %5d\n", n, nums.count_by { _ <= np }) 25 | } 26 | -------------------------------------------------------------------------------- /scripts/RosettaCode/largest_int_from_concatenated_ints.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Largest_int_from_concatenated_ints 5 | # 6 | 7 | func maxnum(nums) { 8 | nums.sort {|x,y| "#{y}#{x}" <=> "#{x}#{y}" }; 9 | } 10 |   11 | [[54, 546, 548, 60], [1, 34, 3, 98, 9, 76, 45, 4]].each { |c| 12 | say maxnum(c).join.to_num; 13 | } 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/last_sunday_of_each_month.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Find_the_last_Sunday_of_each_month 5 | # 6 | 7 | require('DateTime'); 8 | 9 | var year = (ARGV[0] \\ 2015); 10 | 11 | range(1, 12).each { |i| 12 | var date = %s'DateTime'.last_day_of_month( 13 | year => year, 14 | month => i, 15 | ); 16 | 17 | while (date.dow != 7) { 18 | date = date.subtract(days => 1); 19 | }; 20 | 21 | say date.ymd; 22 | } 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/left_factorials.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Left_factorials#Sidef 5 | # 6 | 7 | func left_fact(k) { 8 | sum(^k, { _! }) 9 | } 10 | 11 | [range(0, 10), range(20, 50).by(10)].each { |r| 12 | r.each { |i| 13 | printf("!%d = %s\n", i, left_fact(i)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/letter_frequency.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Letter_frequency#Sidef 5 | # 6 | 7 | func letter_frequency(File file) { 8 | file.read.chars.grep{.match(/[[:alpha:]]/)} \ 9 | .group_by {|letter| letter.downcase} \ 10 | .map_val {|_, val| val.len} \ 11 | .sort_by {|_, val| -val} 12 | } 13 |   14 | var top = letter_frequency(File(__FILE__)) 15 | top.each{|pair| say "#{pair[0]}: #{pair[1]}"} 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/levenshtein_distance.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Levenshtein_distance 5 | # 6 | 7 | func lev(s,t) { 8 |   9 | s == '' && return t.len; 10 | t == '' && return s.len; 11 |   12 | var s1 = s.slice(1); 13 | var t1 = t.slice(1); 14 |   15 | s.first == t.first ? __FUNC__(s1, t1) 16 |  : 1+[ 17 | __FUNC__(s1, t1), 18 | __FUNC__(s, t1), 19 | __FUNC__(s1, t ) 20 | ].min; 21 | }; 22 | 23 | var l = lev("abcz", "aecd"); 24 | 25 | say l 26 | assert_eq(l, 2) 27 | -------------------------------------------------------------------------------- /scripts/RosettaCode/levenshtein_distance_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Levenshtein_distance 5 | # 6 | 7 | func lev(s, t) { 8 | var d = [@^(t.len+1), s.len.of{[_]}...] 9 | { |i| 10 | { |j| 11 | d[i+1][j+1] = ( 12 | s[i] == t[j] ? d[i][j] 13 |  : [d[i][j+1], d[i+1][j], d[i][j]].min+1 14 | ) 15 | } * t.len 16 | } * s.len 17 | d[-1][-1] \\ [s.len, t.len].min 18 | } 19 | 20 | say lev(%c'kitten', %c'sitting'); # prints: 3 21 | say lev(%c'rosettacode', %c'raisethysword'); # prints: 8 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/levenshtein_distance_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Levenshtein_distance 5 | # 6 | 7 | say lev('kitten', 'sitting'); # prints: 3 8 | say lev('rosettacode', 'raisethysword'); # prints: 8 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/literals_floating_point.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Literals/Floating_point 5 | # 6 | 7 | say 1.234; 8 | say .1234; 9 | say 1234e-5; 10 | say 12.34e5; 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/literals_integer.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Literals/Integer 5 | # 6 | 7 | say 255; 8 | say 0xff; 9 | say 0377; 10 | say 0b1111_1111; 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/literals_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Literals/String 5 | # 6 | 7 | 'single quotes with \'embedded quote\' and \\backslash'; 8 | ‚unicode single quoted’; 9 | %q(not interpolating with (nested) parentheses 10 | and newline); 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/literals_string_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Literals/String 5 | # 6 | 7 | var a = 42; 8 | say "double \Uquotes\E with \"embedded quote\"\nnewline and variable interpolation: #{a} % 10 = #{a % 10}"; 9 | say „same as above”; 10 | say %Q(same as above); 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/literals_string_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Literals/String 5 | # 6 | 7 | var a = 42; 8 | 9 | print < Array { 8 | gather { 9 | combinations(word.len+1, 2, {|i,j| 10 | take(word.substr(i, j-i)) 11 | }) 12 | } 13 | } 14 | 15 | func findLongestCommon(String first, String second) -> String { 16 | createSubstrings(first) & createSubstrings(second) -> max_by { .len } 17 | } 18 | 19 | var substr = findLongestCommon("thisisatest", "testing123testing") 20 | 21 | say substr 22 | assert_eq(substr, "test") 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/look-and-say_sequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Look-and-say_sequence 5 | # 6 | 7 | func lookandsay(str) { 8 | str.gsub(/((.)\2*)/, {|a,b| a.len.to_s + b }); 9 | } 10 |   11 | var num = "1"; 12 | { 13 | say num; 14 | num = lookandsay(num); 15 | } * 10; 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loop_over_multiple_arrays_simultaneously.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loop_over_multiple_arrays_simultaneously 5 | # 6 | 7 | [%w(a b c),%w(A B C),%w(1 2 3)].zip { |i,j,k| 8 | say "#{i}#{j}#{k}" 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_break.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Break 5 | # 6 | 7 | var lim = 20; 8 | while (true) { 9 | say (var n = lim.rand.int); 10 | n == 10 && break; 11 | say lim.rand.int; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_continue.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Continue 5 | # 6 | 7 | for (1..10) { |i| 8 | print i; 9 | if (i %% 5) { 10 | print "\n"; 11 | next; 12 | }; 13 | print ', '; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_do-while.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Do-while 5 | # 6 | 7 | var value = 0; 8 | do { 9 | say ++value; 10 | } while (value % 6); 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_downward_for.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Downward_for 5 | # 6 | 7 | for (var i = 10; i >= 0; i--) { 8 | say i; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_for.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/For 5 | # 6 | 7 | for (var i = 1; i <= 5; i++) { 8 | for (var j = 1; j <= i; j++) { 9 | print '*'; 10 | }; 11 | print "\n"; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_for_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/For 5 | # 6 | 7 | for (1..5) { |i| 8 | for (1..i) { print '*' }; 9 | print "\n"; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_for_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/For 5 | # 6 | 7 | for (1..5) { |i| 8 | for (i..5) { |j| 9 | say '*'*j; break; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_for_with_a_specified_step.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/For_with_a_specified_step 5 | # 6 | 7 | for (var i = 2; i <= 8; i += 2) { 8 | say i; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_foreach.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Foreach 5 | # 6 | 7 | foreach [1,2,3] { |i| 8 | say i; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_foreach_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Foreach 5 | # 6 | 7 | [1,2,3].each { |i| 8 | say i; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_n_plus_one_half.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/N_plus_one_half 5 | # 6 | 7 | for (1..10) { |i| 8 | print i; 9 | i == 10 && break; 10 | print ', '; 11 | } 12 |   13 | print "\n"; 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_nested.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/Nested 5 | # 6 | 7 | var arr = 10.of{ 10.of{ 20.irand + 1 } }; 8 |   9 | for (arr) { |row| 10 | for (row) { |num| 11 | "%3d".printf(num); 12 | num == 20 && goto 'END'; 13 | }; 14 | print "\n"; 15 | }; 16 | @:END; 17 |   18 | print "\n"; 19 | -------------------------------------------------------------------------------- /scripts/RosettaCode/loops_while.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Loops/While 5 | # 6 | 7 | var i = 1024; 8 | while (i > 0) { 9 | say i; 10 | i.div!(2).int!; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/luhn_test_of_credit_card_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func luhn (n) { 4 | var chars = n.to_s.reverse.split(1).map{.to_i}; 5 | var (i, sum) = (0, 0); 6 | static a = (0..9 -> map {|j| (2*j / 10 -> int) + (2*j % 10 -> int) }); 7 | chars.each { |j| 8 | sum += (i++.is_odd ? a[j] : j); 9 | }; 10 | return (sum % 10 == 0); 11 | } 12 | 13 | # Test and display 14 | [49927398716, 49927398717, 1234567812345678, 1234567812345670].each { |n| 15 | say [n, luhn(n)].dump; 16 | } 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/map_range.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Map_range 5 | # 6 | 7 | func map_range(a, b, x) { 8 | var (a1, a2, b1, b2) = (a.bounds, b.bounds); 9 | x-a1 * b2-b1 / a2-a1 + b1; 10 | } 11 |   12 | var a = 0..^10; 13 | var b = -1..^0; 14 |   15 | a.each { |x| 16 | say "#{x} maps to #{map_range(a, b, x)}"; 17 | } 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/matrix_transposition.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Matrix_transposition 5 | # 6 | 7 | func transpose(matrix) { 8 | matrix[0].range.map{|i| matrix.map{_[i]}}; 9 | }; 10 |   11 | var m = [ 12 | [1, 1, 1, 1], 13 | [2, 4, 8, 16], 14 | [3, 9, 27, 81], 15 | [4, 16, 64, 256], 16 | [5, 25, 125, 625], 17 | ]; 18 |   19 | transpose(m).each { |row| 20 | "%5d" * row.len -> printlnf(row...); 21 | } 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/md5.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/MD5 5 | # 6 | 7 | var digest = frequire('Digest::MD5'); 8 | say digest.md5_hex("The quick brown fox jumped over the lazy dog's back"); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/md5_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/MD5 5 | # 6 | 7 | var md5 = require('Digest::MD5').new; 8 | md5.add("The quick brown fox jumped over the lazy dog's back"); 9 | say md5.hexdigest; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/middle_three_digits.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Middle_three_digits 5 | # 6 | 7 | func middle_three(n) { 8 | var s = n.to_i.abs.to_s; 9 | var l = s.len; 10 | if (l < 3) { "#{n} is too short" } 11 | elsif (l.is_even) { "#{n} has an even number of digits" } 12 | else { "The three middle digits of #{n} are: " + s.substr(l-3 / 2, 3) } 13 | } 14 | 15 | var nums = %n( 16 | 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 17 | 1 2 -1 -10 2002 -2002 0 18 | ); 19 | nums.each { say middle_three(_) }; 20 | -------------------------------------------------------------------------------- /scripts/RosettaCode/modular_arithmetic.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Modular_arithmetic 5 | # 6 | 7 | class Modulo(n=0, m=13) { 8 | 9 | method init { 10 | (n, m) = (n % m, m) 11 | } 12 | 13 | method to_n { n } 14 | 15 | < + - * ** >.each { |meth| 16 | Modulo.def_method(meth, method(n2) { Modulo(n.(meth)(n2.to_n), m) }) 17 | } 18 | 19 | method to_s { "#{n} 「mod #{m}」" } 20 | } 21 | 22 | func f(x) { x**100 + x + 1 } 23 | var res = f(Modulo(10, 13)) 24 | 25 | assert_eq(res.n, 1) 26 | assert_eq(res.m, 13) 27 | 28 | say res 29 | -------------------------------------------------------------------------------- /scripts/RosettaCode/modular_exponentiation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Modular_exponentiation 5 | # 6 | 7 | func expmod(a, b, n) { 8 | var c = 1 9 | do { 10 | (c *= a) %= n if b.is_odd 11 | (a *= a) %= n 12 | } while (b //= 2) 13 | c 14 | } 15 | 16 | var result = expmod( 17 | 2988348162058574136915891421498819466320163312926952423791023078876139, 18 | 2351399303373464486466122544523690094744975233415544072992656881240319, 19 | 10**40) 20 | 21 | assert_eq(result, 1527229998585248450016808958343740453059) 22 | say result 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/modular_inverse.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func invmod(a, n) { 4 | var (t, nt, r, nr) = (0, 1, n, a % n) 5 | while (nr != 0) { 6 | var quot = int((r - (r % nr)) / nr); 7 | (nt, t) = (t - quot*nt, nt); 8 | (nr, r) = (r - quot*nr, nr); 9 | } 10 | r > 1 && return() 11 | t < 0 && (t += n) 12 | t 13 | } 14 | 15 | var n = invmod(42, 2017) 16 | 17 | say n 18 | assert_eq(42.invmod(2017), n) 19 | -------------------------------------------------------------------------------- /scripts/RosettaCode/multifactorial.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Multifactorial 5 | # 6 | 7 | func mfact(s, n) { 8 | n > 0 ? (n * mfact(s, n-s)) : 1; 9 | } 10 |   11 | for s in range(1, 10) { 12 | say "step=#{s}: #{1..10 -> map {|n| mfact(s, n)}.join(' ')}"; 13 | } 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/multiple_distinct_objects.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Multiple_distinct_objects 5 | # 6 | 7 | class Foo { }; 8 | 9 | [Foo.new] * 5; # incorrect (only one distinct object is created) 10 | 11 | 5.of {Foo.new}; # correct 12 | 1..5 -> map {Foo.new}; # also correct 13 | -------------------------------------------------------------------------------- /scripts/RosettaCode/multiplication_tables.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Multiplication_tables 5 | # 6 | 7 | var max = 12; 8 | var width = (max**2 -> len+1); 9 |   10 | func fmt_row(*items) { 11 | items.map { |s| "%*s" % (width, s) }.join(''); 12 | } 13 |   14 | say fmt_row('x┃', (1..max)...); 15 | say "#{'━' * (width - 1)}╋#{'━' * (max * width)}"; 16 |   17 | for i in (1..max) { 18 | say fmt_row("#{i}┃", (1..max).map {|j| i <= j ? i*j : ''}...); 19 | } 20 | -------------------------------------------------------------------------------- /scripts/RosettaCode/multisplit.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Multisplit 5 | # 6 | 7 | func multisplit(sep, str, :opt) { 8 | sep = sep.map{.escape}.join('|'); 9 | var re = Regex.new(opt{:keep_sep} ? "(#{sep})" : sep); 10 | str.split(re, -1); 11 | } 12 |   13 | [false, true].each { |bool| 14 | say multisplit(%w(== != =), 'a!===b=!=c', keep_sep => bool); 15 | } 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/nested_function.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Nested_function 5 | # 6 | 7 | func make_list(separator = ') ') { 8 | 9 | var count = 1 10 | func make_item(item) { 11 | [count++, separator, item].join 12 | } 13 | 14 | «call« make_item -> join("\n") 15 | } 16 | 17 | say make_list('. ') 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/nth.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/N'th 5 | # 6 | 7 | func nth(n) { 8 | static irregulars = Hash.new(<1 ˢᵗ 2 ⁿᵈ 3 ʳᵈ 11 ᵗʰ 12 ᵗʰ 13 ᵗʰ>...); 9 | n.to_s + (irregulars{n % 100} \\ irregulars{n % 10} \\ 'ᵗʰ'); 10 | } 11 | 12 | [range(0, 25), range(250, 265), range(1000, 1025)].each { |r| 13 | say r.map {|n| nth(n) }.join(" "); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/partial_function_application.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Partial_function_application 5 | # 6 | 7 | func fs(f) { 8 | func(*args) { 9 | args.map {f(_)} 10 | } 11 | } 12 | 13 | func double(n) { n * 2 }; 14 | func square(n) { n ** 2 }; 15 | 16 | var fs_double = fs(double); 17 | var fs_square = fs(square); 18 | 19 | var s = (0 .. 3); 20 | say "fs_double(#{s}): #{fs_double(s...)}"; 21 | say "fs_square(#{s}): #{fs_square(s...)}"; 22 | 23 | s = [2, 4, 6, 8]; 24 | say "fs_double(#{s}): #{fs_double(s...)}"; 25 | say "fs_square(#{s}): #{fs_square(s...)}"; 26 | -------------------------------------------------------------------------------- /scripts/RosettaCode/pascal_s_triangle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Pascal's_triangle 5 | # 6 | 7 | func pascal(rows) { 8 | var row = [1]; 9 | { | n| 10 | say row.join(' '); 11 | row = [1, ^n -> map {|i| row[i] + row[i+1] }..., 1]; 12 | } * rows; 13 | } 14 | 15 | pascal(10); 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/pernicious_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Pernicious_numbers#Sidef 5 | # 6 | 7 | func is_pernicious(n) { 8 | var c = 2693408940; # primes < 32 as set bits 9 | while (n > 0) { c >>= 1; n &= (n - 1) } 10 | c & 1; 11 | } 12 | 13 | var (i, *p) = 0; 14 | while (p.len < 25) { 15 | p << i if is_pernicious(i); 16 | ++i; 17 | } 18 | 19 | say p.join(' '); 20 | 21 | var (i, *p) = 888888877; 22 | while (i < 888888888) { 23 | p << i if is_pernicious(i); 24 | ++i; 25 | } 26 | 27 | say p.join(' '); 28 | -------------------------------------------------------------------------------- /scripts/RosettaCode/phrase_reversals.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Phrase_reversals 5 | # 6 | 7 | var str = "rosetta code phrase reversal"; 8 |   9 | say str.reverse; # reversed string 10 | say str.words.map{.reverse}.join(' '); # words reversed 11 | say str.words.reverse.join(' '); # word order reversed 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/pick_random_element.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Pick_random_element 5 | # 6 | 7 | var arr = %w(north east south west); 8 | say arr.rand; 9 | say arr.rand(2).dump; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/pointers_and_references.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Pointers_and_references 5 | # 6 | 7 | func assign2ref(ref, value) { 8 | *ref = value; 9 | } 10 |   11 | var x = 10; 12 | assign2ref(\x, 20); 13 | say x; # x is now 20 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/primality_by_trial_division.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Primality_by_trial_division 5 | # 6 | 7 | func is_prime(a) { 8 | given (a) { 9 | when (2) { true } 10 | case (a <= 1 || a.is_even) { false } 11 | default { range(3, a.sqrt) -> any { .divides(a) } -> not } 12 | } 13 | } 14 | 15 | 25.times { |i| 16 | is_prime(i) && say i; 17 | } 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/program_name.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Program_name 5 | # 6 | 7 | say __MAIN__; 8 | if (__MAIN__ != __FILE__) { 9 | say "This file has been included!"; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/queue_definition_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class FIFO(*array) { 4 | method pop { 5 | self.empty && die "underflow"; 6 | array.shift; 7 | }; 8 | method push(*items) { 9 | array += items; 10 | self; 11 | }; 12 | method empty { 13 | array.len == 0; 14 | }; 15 | }; 16 | 17 | var f = FIFO(); 18 | say f.empty; # true 19 | f.push('foo'); 20 | f.push('bar', 'baz'); 21 | say f.pop; # foo 22 | say f.empty; # false 23 | 24 | var g = FIFO('xxx', 'yyy'); 25 | say g.pop; # xxx 26 | say f.pop; # bar 27 | -------------------------------------------------------------------------------- /scripts/RosettaCode/quickselect_algorithm.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Quickselect_algorithm 5 | # 6 | 7 | func quickselect(a, k) { 8 | var pivot = a.pick; 9 | var left = a.grep{|i| i < pivot}; 10 | var right = a.grep{|i| i > pivot}; 11 |   12 | given(var l = left.len) { 13 | when(k) { pivot } 14 | case(k < l) { __FUNC__(left, k) } 15 | default { __FUNC__(right, k - l - 1) } 16 | } 17 | } 18 |   19 | var v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]; 20 | var arr = v.range.map{|i| quickselect(v, i)}; 21 | 22 | say arr; 23 | assert_eq(arr, v.sort); 24 | -------------------------------------------------------------------------------- /scripts/RosettaCode/quine_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Quine 5 | # 6 | 7 | say(<[+-]?[0-9]+) ) 11 | (?(?&int))-(?(?&int)) 12 | $/x) 13 | m ? do {var c = m.ncap; @(Num(c{:from}) .. Num(c{:to}))} 14 | : Num(r) 15 | } 16 | } 17 | 18 | var rstr = rangex('-6,-3--1,3-5,7-11,14,15,17-20').flatten.join(','); 19 | assert_eq(rstr, "-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20"); 20 | 21 | say rstr; 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/read_a_file_line_by_line.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Read_a_file_line_by_line 5 | # 6 | 7 | File(__FILE__).open_r.each { |line| 8 | say line; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/read_a_file_line_by_line_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Read_a_file_line_by_line 5 | # 6 | 7 | var fh = File.new(__FILE__).open_r; 8 | while (fh.readline(\var line)) { 9 | say line; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/read_a_specific_line_from_a_file.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Read_a_specific_line_from_a_file 5 | # 6 | 7 | func getNthLine(filename, n) { 8 | var file = File.new(filename); 9 | file.open_r.each { |line| 10 | Num($.) == n && return line; 11 | }; 12 | Sys.warn("file #{file} does not have #{n} lines, only #{Num($.)}\n"); 13 | return nil; 14 | } 15 |   16 | var wantedLine = getNthLine("/etc/passwd", 7); 17 | defined(wantedLine) && print wantedLine; 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/read_entire_file.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Read_entire_file 5 | # 6 | 7 | var file = File.new(__FILE__); 8 | var content = file.open_r.slurp; 9 | print content; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/regular_expressions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Regular_expressions 5 | # 6 | 7 | var str = "I am a string"; 8 | if (str =~ /string$/) { 9 | print "Ends with 'string'\n"; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/regular_expressions_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Regular_expressions 5 | # 6 | 7 | var str = <<'EOF'; 8 | x:Foo 9 | y:Bar 10 | EOF 11 |   12 | while (var m = str=~/(\w+):(\S+)/g) { 13 | say "#{m[0]} -> #{m[1]}"; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/regular_expressions_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Regular_expressions 5 | # 6 | 7 | var str = "I am a string"; 8 |   9 | # Substitute something mached by a regex 10 | str.sub!(/ a /, ' another '); # "I am a string" => "I am another string" 11 |   12 | # Remove something matched by a regex 13 | str -= / \Kanother /i; # "I am another string" => "I am string" 14 |   15 | # Global subtitution with a block 16 | str = str.gsub(/(\w+)/, {|s1| 'x' * s1.len}); # globaly replace any word with 'xxx' 17 |   18 | say str; # prints: 'x xx xxxxxx' 19 | -------------------------------------------------------------------------------- /scripts/RosettaCode/remove_duplicate_elements.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Remove_duplicate_elements 5 | # 6 | 7 | var ary = [1,1,2,1,'redundant',[1,2,3],[1,2,3],'redundant']; 8 | say ary.uniq.dump; 9 | say ary.last_uniq.dump; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/rename_a_file.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Rename_a_file 5 | # 6 | 7 | # Here 8 | File.rename('input.txt', 'output.txt'); 9 | File.rename('docs', 'mydocs'); 10 |   11 | # Root dir 12 | File.rename(Dir.root + %f'input.txt', Dir.root + %f'output.txt'); 13 | File.rename(Dir.root + %f'docs', Dir.root + %f'mydocs'); 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/rep-string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Rep-string 5 | # 6 | 7 | var array = <1001110011 1110111011 8 | 0010010010 1010101010 9 | 1111111111 0100101101 10 | 0100100 101 11 00 1>; 11 |   12 | array.each { |n| 13 | if (var m = (n =~ /^(.+)\1+(.*$)(?(?{ substr($1, 0, length $2) eq $2 })|(?!))/)) { 14 | var i = m[0].len; 15 | say (n.substr(0, i), 16 | n.substr(i, i).tr('01', '𝟘𝟙'), 17 | n.substr(i*2)); 18 | } else { 19 | say "#{n} (no repeat)"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/repeat.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Repeat 5 | # 6 | 7 | func repeat(f, n) { 8 | { f() } * n; 9 | } 10 |   11 | func example { 12 | say "Example"; 13 | } 14 |   15 | repeat(example, 4); 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/repeat_a_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Repeat_a_string 5 | # 6 | 7 | say ('ha' * 5); # ==> 'hahahahaha' 8 | -------------------------------------------------------------------------------- /scripts/RosettaCode/return_multiple_values.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Return_multiple_values 5 | # 6 | 7 | func foo(a,b) { 8 | return (a+b, a*b); 9 | }; 10 | 11 | var (x, y) = foo(4, 5); 12 | 13 | say x; 14 | say y; 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/reverse_a_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Reverse_a_string 5 | # 6 | 7 | say "asdf".reverse; # fdsa 8 | say "résumé niño".reverse; # oñin émusér 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/reverse_words_in_a_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Reverse_words_in_a_string 5 | # 6 | 7 | DATA.each{|line| line.words.reverse.join(" ").say}; 8 |   9 | __DATA__ 10 | ---------- Ice and Fire ------------ 11 |   12 | fire, in end will world the say Some 13 | ice. in say Some 14 | desire of tasted I've what From 15 | fire. favor who those with hold I 16 |   17 | ... elided paragraph last ... 18 |   19 | Frost Robert ----------------------- 20 | -------------------------------------------------------------------------------- /scripts/RosettaCode/roots_of_unity_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Roots_of_unity#Sidef 5 | # 6 | 7 | func roots_of_unity (n) { 8 | n.of { |j| 9 | exp(2.i * Complex.pi / n * (j-1)) 10 | } 11 | } 12 | 13 | roots_of_unity(5).each { |c| 14 | printf("%+.5f%+.5fi\n", c.reals); 15 | } 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/runtime_evaluation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Runtime_evaluation 5 | # 6 | 7 | var (a, b) = (-5, 7); 8 | say eval '(a * b).abs'; # => 35 9 | say (a * b -> abs); # => 35 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/runtime_evaluation_in_an_environment.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Runtime_evaluation/In_an_environment 5 | # 6 | 7 | func eval_with_x(code, x, y) { 8 | var f = eval(code); 9 | x = y; 10 | eval(code) - f; 11 | } 12 |   13 | say eval_with_x('2 ** x', 3, 5); # => 24 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/search_a_list.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Search_a_list 5 | # 6 | 7 | var haystack = %w(Zig Zag Wally Ronald Bush Krusty Charlie Bush Bozo); 8 |   9 | %w(Bush Washington).each { |needle| 10 | var i = haystack.first_index{|item| item == needle}; 11 | if (i >= 0) { 12 | say "#{i} #{needle}"; 13 | } else { 14 | say "#{needle} is not in haystack"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/search_a_list_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Search_a_list 5 | # 6 | 7 | var haystack = %w(Zig Zag Wally Ronald Bush Krusty Charlie Bush Bozo); 8 | say haystack.last_index{|item| item == "Bush"}; 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/secure_temporary_file.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Secure_temporary_file 5 | # 6 | 7 | var tmpfile = require('File::Temp'); 8 | var fh = tmpfile.new(UNLINK => 1); 9 | say fh.filename; 10 | fh.print("Hello, World!\n"); 11 | fh.close; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/send_an_unknown_method_call.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Send_an_unknown_method_call 5 | # 6 | 7 | class Example { 8 | method foo(x) { 9 | 42 + x; 10 | } 11 | } 12 |   13 | var name = 'foo'; 14 | var obj = Example(); 15 | say obj.(name)(5); # prints: 47 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sha-1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/SHA-1 5 | # 6 | 7 | var sha = frequire('Digest::SHA'); 8 | say sha.sha1_hex('Rosetta Code'); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sha-256.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/SHA-256 5 | # 6 | 7 | var sha = frequire('Digest::SHA'); 8 | say sha.sha256_hex('Rosetta code'); 9 | -------------------------------------------------------------------------------- /scripts/RosettaCode/short-circuit_evaluation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Short-circuit_evaluation 5 | # 6 | 7 | func a(bool) { print 'A'; return bool }; 8 | func b(bool) { print 'B'; return bool }; 9 |   10 | # Test-driver 11 | func test() { 12 | ['&&', '||'].each { |op| 13 | [[1,1],[1,0],[0,1],[0,0]].each { |pair| 14 | "a(%s) %s b(%s): ".printf(pair[0], op, pair[1]); 15 | eval "a(pair[0].to_bool) #{op} b(pair[1].to_bool)"; 16 | print "\n"; 17 | } 18 | } 19 | } 20 |   21 | # Test and display 22 | test(); 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/show_the_epoch.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Show_the_epoch 5 | # 6 | 7 | say Time(0).gmtime.ctime 8 | -------------------------------------------------------------------------------- /scripts/RosettaCode/singly-linked_list_element_definition.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Singly-linked_list/Element_definition 5 | # 6 | 7 | var foo_node = Hash.new(foo => 1); 8 | var bar_node = Hash.new(bar => 2); 9 | 10 | var node = :( 11 | data => 'say what', 12 | next => foo_node, 13 | ); 14 |   15 | node{:next} = bar_node; # mutable 16 | 17 | say node; 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/singly-linked_list_element_insertion.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Singly-linked_list/Element_insertion 5 | # 6 | 7 | func insert_after(a,b) { 8 | b{:next} = a{:next}; 9 | a{:next} = b; 10 | } 11 |   12 | var B = :( 13 | data => 3, 14 | next => nil, # not a circular list 15 | ); 16 | var A = :( 17 | data => 1, 18 | next => B, 19 | ); 20 | var C = :( 21 | data => 2, 22 | ); 23 |   24 | insert_after(A, C); 25 | 26 | say A; 27 | say B; 28 | say C; 29 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sort_an_integer_array.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_an_integer_array 5 | # 6 | 7 | var nums = [2,4,3,1,2]; 8 | var sorted = nums.sort; # returns a new sorted array. 9 | nums.sort!; # sort 'nums' "in-place" 10 | 11 | say sorted; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sort_disjoint_sublist.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_disjoint_sublist 5 | # 6 | 7 | func disjointSort(values, indices) { 8 | values[indices.sort] = [values[indices]].sort...; 9 | } 10 |   11 | var values = [7, 6, 5, 4, 3, 2, 1, 0]; 12 | var indices = [6, 1, 7]; 13 |   14 | disjointSort(values, indices); 15 | say values; 16 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sort_stability.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_stability 5 | # 6 | 7 | var table = [ 8 | , 9 | , 10 | , 11 | , 12 | ]; 13 |   14 | table.sort {|a,b| a[0] <=> b[0]}.each { |col| 15 | say "#{col[0]} #{col[1]}" 16 | } 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sort_three_variables.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_three_variables 5 | # 6 | 7 | func sort_refs(*arr) { 8 | arr.map{ *_ }.sort ~Z arr -> each { *_[1] = _[0] } 9 | } 10 | 11 | var x = 77444 12 | var y = -12 13 | var z = 0 14 | 15 | sort_refs(\x, \y, \z) 16 | 17 | say x 18 | say y 19 | say z 20 | 21 | assert_eq(x, -12) 22 | assert_eq(y, 0) 23 | assert_eq(z, 77444) 24 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sort_using_a_custom_comparator.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_using_a_custom_comparator 5 | # 6 | 7 | func mycmp(a, b) { (b.len <=> a.len) || (a.lc <=> b.lc) }; 8 | var strings = %w(Here are some sample strings to be sorted); 9 | var sorted = strings.sort(mycmp); 10 | 11 | say sorted; 12 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sorting_algorithms_counting_sort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sorting_algorithms/Counting_sort 5 | # 6 | 7 | func counting_sort(a, min, max) { 8 | var cnt = ([0] * (max - min + 1)) 9 | a.each {|i| cnt[i-min]++ } 10 | cnt.map {|i| [min++] * i }.flat 11 | } 12 |   13 | var a = 100.of {100.irand} 14 | say counting_sort(a, 0, 100) 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sorting_algorithms_quicksort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sorting_algorithms/Quicksort 5 | # 6 | 7 | func quicksort (a) { 8 | a.len < 2 && return(a); 9 | var p = a.pop_rand; # to avoid the worst cases 10 | __FUNC__(a.grep{ .< p}) + [p] + __FUNC__(a.grep{ .>= p}); 11 | } 12 | 13 | var numbers = [7,6,5,9,8,4,3,1,2,0]; 14 | say quicksort(numbers); 15 |   16 | var strs = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"]; 17 | say quicksort(strs); 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sorting_algorithms_sleep_sort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sorting_algorithms/Sleep_sort 5 | # 6 | 7 | ARGV.map{.to_i}.map{ |i| 8 | {Sys.sleep(i); say i}.fork; 9 | }.each{.wait}; 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/split_repchar_string.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character 5 | # 6 | 7 | func group(str) { 8 | gather { 9 | while (var match = (str =~ /((.)\g{-1}*)/g)) { 10 | take(match[0]) 11 | } 12 | } 13 | } 14 | 15 | say group(ARGV[0] \\ 'gHHH5YY++///\\').join(', ') 16 | 17 | assert_eq(group('gHHH5YY++///\\'), ["g", "HHH", "5", "YY", "++", "///", "\\"]) 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/square_but_not_cube.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Square_but_not_cube 4 | 5 | var square_and_cube = Enumerator({|f| 6 | 1..Inf -> each {|n| f(n**6) } 7 | }) 8 |   9 | var square_but_not_cube = Enumerator({|f| 10 | 1..Inf -> lazy.map {|n| n**2 }.grep {|n| !n.is_power(3) }.each {|n| f(n) } 11 | }) 12 |   13 | say "First 30 positive integers that are a square but not a cube:" 14 | say square_but_not_cube.first(30).join(' ') 15 |   16 | say "First 15 positive integers that are both a square and a cube:" 17 | say square_and_cube.first(15).join(' ') 18 | -------------------------------------------------------------------------------- /scripts/RosettaCode/stack.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Stack 5 | # 6 | 7 | var stack = []; 8 | stack.push(42); # pushing 9 | say stack.pop; # popping 10 | say stack.is_empty; # is_emtpy? 11 | -------------------------------------------------------------------------------- /scripts/RosettaCode/stack_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Stack 5 | # 6 | 7 | class Stack(stack=[]) { 8 | method pop { stack.pop }; 9 | method push(item) { stack.push(item) }; 10 | method empty { stack.is_empty }; 11 | } 12 |   13 | var stack = Stack(); 14 | stack.push(42); 15 | say stack.pop; # => 42 16 | say stack.empty; # => true 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/standard_deviation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Standard_deviation 5 | # 6 | 7 | class StdDevAccumulator(n=0, sum=0, sumofsquares=0) { 8 | method <<(num) { 9 | n += 1; 10 | sum += num; 11 | sumofsquares += num**2; 12 | self; 13 | } 14 | 15 | method stddev { 16 | sqrt(sumofsquares/n - pow(sum/n, 2)); 17 | } 18 | 19 | method to_s { 20 | self.stddev.to_s; 21 | } 22 | } 23 | 24 | var i = 0; 25 | var sd = StdDevAccumulator.new; 26 | [2,4,4,4,5,5,7,9].each {|n| 27 | say "adding #{n}: stddev of #{i+=1} samples is #{sd << n}" 28 | } 29 | -------------------------------------------------------------------------------- /scripts/RosettaCode/standard_deviation_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Standard_deviation 5 | # 6 | 7 | func stddev(x) { 8 | static(num=0, sum=0, sum2=0); 9 | num++; 10 | sqrt( 11 | (sum2 += x**2) / num - 12 | (((sum += x) / num)**2) 13 | ); 14 | } 15 | 16 | %n(2 4 4 4 5 5 7 9).each { say stddev(_) } 17 | -------------------------------------------------------------------------------- /scripts/RosettaCode/string_comparison.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var methods = %w(== != > >= < <= <=>); 4 | 5 | [%w(YUP YUP),%w(YUP Yup),%w(bot bat),%w(aaa zz)].each {|arr| 6 | var (s1, s2) = arr...; 7 | methods.each{|m| "%s %s %s\t%s\n".printf(s1, m, s2, s1.(m)(s2))}; 8 | print "\n"; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/RosettaCode/sum_digits_of_an_integer.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sum_digits_of_an_integer 5 | # 6 | 7 | func Σ(String str, base=36) { 8 | str.chars.map{ Num(_, base) }.sum 9 | } 10 | 11 | <1 1234 1020304 fe f0e DEADBEEF>.each { |n| 12 | say "Σ(#{n}) = #{Σ(n)}" 13 | } 14 | -------------------------------------------------------------------------------- /scripts/RosettaCode/ternary_and_binary_palindrome.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Find_palindromic_numbers_in_both_binary_and_ternary_bases 5 | # 6 | 7 | var format = "%11s %24s %38s\n" 8 | format.printf("decimal", "ternary", "binary") 9 | format.printf(0, 0, 0) 10 | 11 | var nums = [] 12 | 13 | for n in (0 .. 1e3) { 14 | var pal = n.base(3)||'' 15 | var b3 = (pal + '1' + pal.flip) 16 | var b2 = Num(b3, 3).base(2) 17 | if (b2 == b2.flip) { 18 | nums << Num(b2, 2) 19 | format.printf(Num(b2, 2), b3, b2) 20 | } 21 | } 22 | 23 | assert_eq(nums, [1, 6643, 1422773, 5415589]) 24 | -------------------------------------------------------------------------------- /scripts/RosettaCode/thue_morse.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Thue-Morse 5 | # 6 | 7 | func recmap(repeat, seed, transform, callback) { 8 | func (repeat, seed) { 9 | callback(seed) 10 | repeat > 0 && __FUNC__(repeat-1, transform(seed)) 11 | }(repeat, seed) 12 | } 13 | 14 | recmap(6, "0", {|s| s + s.tr('01', '10') }, { .say }) 15 | -------------------------------------------------------------------------------- /scripts/RosettaCode/truncatable_primes.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Truncatable_primes 5 | # 6 | 7 | func t_prime(n, left=true) { 8 | var p = %w(2 3 5 7); 9 | var f = ( 10 | left ? { '1'..'9' ~X+ p } 11 | : { p ~X+ '1'..'9' } 12 | ) 13 | n.times { 14 | p = f().grep{ .to_i.is_prime } 15 | } 16 | p.map{.to_i}.max 17 | } 18 | 19 | var ltp = t_prime(5, left: true) 20 | var rtp = t_prime(5, left: false) 21 | 22 | say ltp; 23 | say rtp; 24 | 25 | assert_eq(ltp, 998443); 26 | assert_eq(rtp, 739399); 27 | -------------------------------------------------------------------------------- /scripts/RosettaCode/utf8_encode_decode.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/UTF-8_encode_and_decode 5 | # 6 | 7 | func utf8_encoder(Number code) { 8 | code.chr.encode('UTF-8').bytes.map{.chr} 9 | } 10 | 11 | func utf8_decoder(Array bytes) { 12 | bytes.map{.ord}.decode('UTF-8') 13 | } 14 | 15 | for n in ([0x0041, 0x00F6, 0x0416, 0x20AC, 0x1D11E]) { 16 | var encoded = utf8_encoder(n) 17 | var decoded = utf8_decoder(encoded) 18 | assert_eq(n, decoded.ord) 19 | say "#{decoded} -> #{encoded}" 20 | } 21 | -------------------------------------------------------------------------------- /scripts/RosettaCode/van_der_corput_sequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Van_der_Corput_sequence 5 | # 6 | 7 | func vdc(value, base=2) { 8 | while (value[-1] > 0) { 9 | value.append(value[-1] / base -> int); 10 | } 11 | var (x, sum) = (1, 0); 12 | value.each { |i| 13 | sum += ((i % base) / (x *= base)); 14 | } 15 | return sum; 16 | } 17 | 18 | 2.to(5).each { |base| 19 | var seq = (9.range.map {|i| vdc([i], base) }); 20 | "base %d: %s\n".printf(base, seq.map{|n| "%.4f" % n}.join(', ')); 21 | } 22 | -------------------------------------------------------------------------------- /scripts/RosettaCode/walk_a_dir_non_recursively.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Walk_a_directory/Non-recursively#Sidef 5 | # 6 | 7 | func file_match(Block callback, pattern=/\.txt\z/, path=Dir.cwd) { 8 | path.open(\var dir_h) || return(); 9 | dir_h.entries.each { |entry| 10 | if (entry.basename ~~ pattern) { 11 | callback(entry); 12 | } 13 | } 14 | } 15 | 16 | file_match( 17 | path: %d'/tmp', 18 | pattern: /\.p[lm]\z/i, 19 | callback: { |file| 20 | say file; 21 | } 22 | ); 23 | -------------------------------------------------------------------------------- /scripts/RosettaCode/word_wrap.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Word_wrap 5 | # 6 | 7 | class String { 8 | method wrap(width) { 9 | var txt = self.gsub(/\s+/, " "); 10 | var len = txt.len; 11 | var para = []; 12 | var i = 0; 13 | while (i < len) { 14 | var j = (i + width); 15 | while ((j < len) && (txt.char_at(j) != ' ')) { --j }; 16 | para.append(txt.substr(i, j-i)); 17 | i = j+1; 18 | }; 19 | return para.join("\n"); 20 | } 21 | } 22 | 23 | var text = 'aaa bb cc ddddd'; 24 | say text.wrap(6); 25 | -------------------------------------------------------------------------------- /scripts/Tests/Module/Bar.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class Bar { 4 | method baz { 5 | "bar"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scripts/Tests/Module/Fact.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func factorial(n) { 4 | n < 1 ? 1 : (n * __FUNC__(n-1)); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/Tests/Module/Fib.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func fibonacci(n) { 4 | n < 2 ? n : (__FUNC__(n-1) + __FUNC__(n-2)); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/Tests/Module/Foo.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class Bar { 4 | method baz { 5 | "foo"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scripts/Tests/Module/Test.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | subset foo < Str, Num 4 | 5 | struct Bar { 6 | a < foo, 7 | b < foo, 8 | } 9 | 10 | var t = Bar(:hi, 100) 11 | 12 | assert_eq(t.a, :hi) 13 | assert_eq(t.b, 100) 14 | 15 | do { 16 | var ok = false 17 | 18 | try { 19 | Bar([], {}) 20 | } 21 | catch { 22 | ok = true 23 | } 24 | 25 | assert(ok) 26 | } 27 | -------------------------------------------------------------------------------- /scripts/Tests/Module/YouTube.sm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class String { 4 | method as_youtube_url { 5 | "https://www.youtube.com/watch?v=#{self}" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scripts/Tests/amb.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Amb#Perl 4 | 5 | var w = [ 6 | "the|,that|,a|", 7 | "frog|,elephant|,thing|", 8 | "walked|,treaded|,grows|", 9 | "slowly|,quickly|", 10 | ]; 11 | 12 | for (w.map{'{'+_+'}'}->join.glob) { |i| 13 | i.gsub!('|', ' ') ~~ 14 | /\w+?(\w) \1\w+?(\w) \2\w+?(\w) \3\w+/ && (i.say); 15 | } 16 | -------------------------------------------------------------------------------- /scripts/Tests/array_any_all.sf: -------------------------------------------------------------------------------- 1 | #! /usr/bin/ruby 2 | 3 | assert_eq( true, [true, true].all{ _ } ) 4 | assert_eq( true, [true, true].all ) 5 | assert_eq( false, [false, true].all{ _ } ) 6 | assert_eq( false, [false, true].all ) 7 | 8 | assert_eq( true, [4, 2, 0].none{ .is_odd } ) 9 | assert_eq( true, [false, false].none{ _ } ) 10 | assert_eq( true, [false, false].none ) 11 | assert_eq( false, [false, true].none ) 12 | 13 | assert_eq( true, [false, true].any{ _ }) 14 | assert_eq( true, [false, true].any) 15 | assert_eq( true, [1, 2, 0, 3].any{ .is_zero } ) 16 | assert_eq( false, [true, true].any{ !_ } ) 17 | 18 | say "** Test passed!" 19 | -------------------------------------------------------------------------------- /scripts/Tests/array_compare.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Comparing two arrays 4 | 5 | var arr1 = [1,2,3,4,5]; 6 | var arr2 = [1,2,3,4]; 7 | 8 | assert_eq(arr1 <=> arr2, 1); 9 | assert_eq(arr2 <=> arr1, -1); 10 | 11 | var arr3 = [["a"], ["z"]]; 12 | var arr4 = [["a"], ["b"]]; 13 | 14 | assert_eq(arr3 <=> arr4, 1); 15 | assert_eq(arr4 <=> arr3, -1); 16 | 17 | #assert_eq(arr1 <=> arr3, -1); 18 | #assert_eq(arr3 <=> arr1, 1); 19 | 20 | assert_eq(arr1, arr1); 21 | assert_eq(arr3, arr3); 22 | 23 | arr3[-1] = ["b"]; 24 | assert_eq(arr3, arr4); 25 | 26 | say "** Test passed!"; 27 | -------------------------------------------------------------------------------- /scripts/Tests/array_flattening.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Test array flattening (`Array.flat` method) 4 | 5 | var arr = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []] 6 | assert_eq(arr.flat, @(1..8)) 7 | 8 | # Cyclic references 9 | var a = [1,[2],3] 10 | a[3] = a 11 | 12 | assert_eq(a.flat, [1,2,3,1,2,3]) 13 | 14 | # Pair objects 15 | assert_eq(Pair([3],Pair([4], 5)).flat, [3,4,5]) 16 | assert_eq([Pair([3],Pair([4], 5))].flat, [3,4,5]) 17 | assert_eq([[Pair([3],Pair([4], 5))]].flat, [3,4,5]) 18 | assert_eq([[Pair([3,[]],[[Pair([[],4], [[[5]]])]])]].flat, [3,4,5]) 19 | 20 | say "** Test passed!" 21 | -------------------------------------------------------------------------------- /scripts/Tests/averages_mode.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Averages/Mode#Perl 4 | 5 | func mode (a) { 6 | 7 | var m = Hash.new; 8 | a.each { |i| 9 | m{i} := 0 ++; 10 | } 11 | 12 | var best = m.values.max; 13 | m.keys.grep { m{_} == best }; 14 | }; 15 | 16 | mode([2, 7, 1, 8, 2]).dump.say; 17 | mode([2, 7, 1, 8, 2, 8]).dump.say; 18 | mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]).dump.say; 19 | mode([1, 1, 2, 4, 4]).dump.say; 20 | -------------------------------------------------------------------------------- /scripts/Tests/balanced_brakets.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func balanced (str) { 4 | 5 | var depth = 0; 6 | str.each { |c| 7 | if(c=='['){ ++depth } 8 | elsif(c==']'){ --depth < 0 && return false } 9 | }; 10 | 11 | return !depth; 12 | } 13 | 14 | [']','[','[[]','][]','[[]]','[[]]]][][]]','x[ y [ [] z ]][ 1 ][]abcd'].each { |str| 15 | printf("%sbalanced\t: %s\n", balanced(str) ? "" : "NOT ", str); 16 | }; 17 | -------------------------------------------------------------------------------- /scripts/Tests/basic_interpreter.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var AST = Hash( 4 | self => Number(1), 5 | call => [ 6 | Hash(method => "add", arg => [Hash(self => Number(2))]), 7 | Hash(method => "add", arg => [Hash(self => Number(3))]), 8 | ], 9 | ) 10 | 11 | func execute(expr) { 12 | var self_obj = expr{"self"} 13 | for call in (expr{"call"}) { 14 | self_obj = self_obj.(call{"method"})(call{"arg"}.map{execute(_)}...) 15 | } 16 | return self_obj 17 | } 18 | 19 | assert_eq(execute(AST), 6) 20 | 21 | say "** Test passed!" 22 | -------------------------------------------------------------------------------- /scripts/Tests/beadsort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sorting_algorithms/Bead_sort#Sidef 5 | # 6 | 7 | func beadsort(arr) { 8 | 9 | var columns = []; 10 | var rows = []; 11 | 12 | arr.each { |datum| 13 | range(0, datum-1).each { |column| 14 | ++(columns[column] := 0); 15 | ++(rows[columns[column] - 1] := 0); 16 | } 17 | } 18 | 19 | rows.reverse; 20 | } 21 | 22 | var arr = [5,3,1,7,4,1,1]; 23 | assert_eq(beadsort(arr), [1, 1, 1, 3, 4, 5, 7]); 24 | 25 | say "** Test passed!"; 26 | -------------------------------------------------------------------------------- /scripts/Tests/binary_search.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func binary_search(a,i) { 4 | 5 | var l = 0; 6 | var h = a.end; 7 | 8 | while (h >= l) { 9 | var mid = (h+l / 2 -> int); 10 | a[mid] > i && (h = mid-1; next); 11 | a[mid] < i && (l = mid+1; next); 12 | return mid; 13 | } 14 | 15 | return -1; 16 | } 17 | 18 | 19 | ## 20 | # Testing 21 | ## 22 | 23 | var min = 1; 24 | var max = 99; 25 | 26 | var a = @(min..max) 27 | 28 | for i in [@|(min .. min+5), @|(max-5 .. max)] { 29 | say i 30 | assert_eq(binary_search(a, i), i-1) 31 | } 32 | 33 | say "Test passed!" 34 | -------------------------------------------------------------------------------- /scripts/Tests/block_identities.sf: -------------------------------------------------------------------------------- 1 | #! /usr/bin/ruby 2 | 3 | 10.times{ 4 | assert_eq(0..100 -> map(Block.identity), 0..100 -> to_a) 5 | assert_eq(Hash(1, 2, 3, 4, 5, 6) -> map_kv(Block.list_identity), Hash(1, 2, 3, 4, 5, 6)) 6 | } 7 | 8 | say "** Test passed!" 9 | -------------------------------------------------------------------------------- /scripts/Tests/caesar_cipher.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Caesar_cipher 5 | # 6 | 7 | func caesar(msg, key, decode=false) { 8 | decode && (key = (26 - key)); 9 | msg.gsub(/([A-Z])/i, {|c| ((c.uc.ord - 65 + key) % 26) + 65 -> chr}); 10 | }; 11 | 12 | var msg = 'THE FIVE BOXING WIZARDS JUMP QUICKLY'; 13 | 14 | var enc = caesar(msg, 10); 15 | var dec = caesar(enc, 10, true); 16 | 17 | say "msg: #{msg}"; 18 | say "enc: #{enc}"; 19 | say "dec: #{dec}"; 20 | 21 | assert_eq(dec, msg); 22 | -------------------------------------------------------------------------------- /scripts/Tests/catalan_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func f(i) { i.is_zero ? 1 : (i * f(i-1)) }; 4 | func c(n) { f(2*n) / f(n) / f(n+1) }; 5 | 6 | for i in (0..15) { 7 | say "#{i}\t#{c(i)}"; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/Tests/catalan_numbers_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func c(n) is cached { 4 | n == 0 ? 1 : (c(n-1) * (4 * n - 2) / (n + 1)) 5 | } 6 | 7 | 15.times { |i| 8 | say "#{i}\t#{c(i)}"; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/Tests/class_inside_module.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | module Hi { 4 | func foo(a, b) { 5 | "Hi #{a} #{b}" 6 | } 7 | 8 | class Hey { 9 | method foo(a, b) { 10 | "Hey #{a} #{b}" 11 | } 12 | } 13 | } 14 | 15 | assert_eq(Hi::foo(1,2), "Hi 1 2") 16 | assert_eq(Hi::Hey().foo(1,2), "Hey 1 2") 17 | 18 | say "** Test passed!" 19 | -------------------------------------------------------------------------------- /scripts/Tests/code_interpolation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Code interpolation: 5 | # 6 | # "Hello #{name}" 7 | ## means: "Hello" + ({name}.run.to_s) 8 | # 9 | 10 | 5.times { |i| 11 | print "#{i} + #{i} == #{i + i}\t"; 12 | print "2*i == 2*#{i} => #{ 2*i }"+"\n"; 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/constant_folding.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var a = %w(a b c b).freq 4 | var b = %w().freq 5 | var c = %w().freq 6 | 7 | assert_eq(b, c) 8 | assert_ne(b.object_id, c.object_id) 9 | assert_eq(a, Hash(a => 1, b => 2, c => 1)) 10 | 11 | say "** Test passed!" 12 | -------------------------------------------------------------------------------- /scripts/Tests/cpp_input_output.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | DATA >> \var x; 4 | STDOUT << x << "\n"; 5 | 6 | __DATA__ 7 | Hello, World! 8 | -------------------------------------------------------------------------------- /scripts/Tests/cramers_rule_matrix_class.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Cramer's rule, using the Matrix class 4 | # https://rosettacode.org/wiki/Cramer%27s_rule 5 | 6 | func cramers_rule(A, terms) { 7 | ^A -> map {|i| 8 | A.dclone.set_column(i, terms).det 9 | } »/» A.det 10 | } 11 | 12 | var matrix = Matrix( 13 | [2, -1, 5, 1], 14 | [3, 2, 2, -6], 15 | [1, 3, 3, -1], 16 | [5, -2, -3, 3], 17 | ) 18 | 19 | var free_terms = [-3, -32, -47, 49] 20 | 21 | assert_eq(cramers_rule(matrix, free_terms), [2, -12, -4, 1]) 22 | 23 | say "** Test passed!" 24 | -------------------------------------------------------------------------------- /scripts/Tests/cyclic_dclone.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Test Object.dclone() on cyclic references 5 | # 6 | 7 | var src = Hash(foo => 0, bar => [0,1]) 8 | 9 | # Add a cyclic reference 10 | src{:baz} = src 11 | 12 | # Make a deep clone 13 | var dst = src.dclone 14 | 15 | # The address of src 16 | assert_eq(src.object_id, src{:baz}.object_id) 17 | assert_ne(src.object_id, 0) 18 | 19 | # The address of dst 20 | assert_eq(dst.object_id, dst{:baz}.object_id) 21 | assert_ne(dst.object_id, 0) 22 | 23 | assert_ne(src.object_id, dst.object_id) 24 | 25 | say "** Test passed!" 26 | -------------------------------------------------------------------------------- /scripts/Tests/data_handle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var str = "sidef"; 4 | 5 | DATA.each { |line| 6 | str = (str.(line.chomp)); 7 | } 8 | 9 | ## Seeking the begining of DATA 10 | DATA.seek(0, 0); 11 | 12 | ## Storing the DATA inside a variable. 13 | var dataFh = DATA; 14 | 15 | while (var line = dataFh.readline) { 16 | say "We have line: <#{line.chomp}>"; 17 | } 18 | 19 | __DATA__ 20 | uc 21 | say 22 | -------------------------------------------------------------------------------- /scripts/Tests/draw_grid_of_squares_multi.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func draw_grid(n, k) { 4 | 5 | if (n % k != 0) { 6 | warn "#{n} is not divisible by #{k}" 7 | } 8 | 9 | func sym( (true), (true) ) { '+' } 10 | func sym( (true), (false) ) { '-' } 11 | func sym( (false), (true) ) { '|' } 12 | func sym( (false), (false) ) { ' ' } 13 | 14 | 0..n -> map {|a| 15 | 0..n -> map {|b| 16 | sym(a %% n/k, b %% n/k) 17 | }.join 18 | }.join("\n").say 19 | } 20 | 21 | draw_grid(25, 5) 22 | draw_grid(16, 2) 23 | draw_grid(12, 3) 24 | -------------------------------------------------------------------------------- /scripts/Tests/draw_grid_of_squares_multi_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func draw_grid(n, k) { 4 | 5 | if (n % k != 0) { 6 | warn "#{n} is not divisible by #{k}" 7 | } 8 | 9 | func sym( {_}, {_} ) { '+' } 10 | func sym( {_}, {!_} ) { '-' } 11 | func sym( {!_}, {_} ) { '|' } 12 | func sym( {!_}, {!_} ) { ' ' } 13 | 14 | 0..n -> map {|a| 15 | 0..n -> map {|b| 16 | sym(a %% n/k, b %% n/k) 17 | }.join 18 | }.join("\n").say 19 | } 20 | 21 | draw_grid(25, 5) 22 | draw_grid(16, 2) 23 | draw_grid(12, 3) 24 | -------------------------------------------------------------------------------- /scripts/Tests/echo.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Examples: 4 | # perl sidef echo.sf -e 'hello there.\nHow are you?' 5 | # perl sidef echo.sf Sidef is awesome. 6 | 7 | if ((ARGV.len >= 1) && (ARGV[0] == '-e')) { 8 | ARGV.shift; 9 | say ARGV.join(" ").apply_escapes; 10 | } 11 | else { 12 | say ARGV.join(" "); 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/eq_g2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func g2(a,b,c) { 4 | var dt = (b**2 - 4*a*c); 5 | var x1 = ((-b + dt.sqrt) / 2*a); 6 | var x2 = ((-b - dt.sqrt) / 2*a); 7 | (x1, x2); 8 | } 9 | 10 | # x^2 + 2x - 8 = 0 11 | var (a, b) = g2(1, 2, -8); 12 | 13 | assert_eq(a, 2); 14 | assert_eq(b, -4); 15 | 16 | say '** Test passed!'; 17 | -------------------------------------------------------------------------------- /scripts/Tests/extended_builtin_class.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func sierpinski_triangle(n) -> Array { 4 | var triangle = ['*'] 5 | { |i| 6 | var sp = (' ' * pow(2, i)); 7 | triangle = (triangle.map {|x| sp + x + sp} + 8 | triangle.map {|x| x + ' ' + x}) 9 | } * n 10 | triangle 11 | } 12 | 13 | class Array { 14 | method display_2d { 15 | say self.join("\n") 16 | } 17 | } 18 | 19 | sierpinski_triangle(3).display_2d 20 | -------------------------------------------------------------------------------- /scripts/Tests/fibonacci_closed_solution.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func fibonacci (n) { 4 | 5 | define S = (1.25.sqrt + 0.5); 6 | define T = (-S + 1); 7 | 8 | (S**n - T**n) / (-T + S) -> roundf(0); 9 | } 10 | 11 | for (0..10) { |i| 12 | say fibonacci(i); 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/fibonacci_iterative.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Fibonacci_sequence 4 | 5 | func fib_iter(n) { 6 | var fib = [1, 1]; 7 | { 8 | fib = [fib[-1], fib[-2] + fib[-1]] 9 | } * (n - fib.len); 10 | return fib[-1]; 11 | } 12 | 13 | assert_eq(fib_iter(5), 5); 14 | assert_eq(fib_iter(12), 144); 15 | 16 | say "** Test passed!"; 17 | -------------------------------------------------------------------------------- /scripts/Tests/filehandles.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Tests for various file-handles. 4 | 5 | var buf = FileHandle.new_buf(:raw, "foo") 6 | buf.print("bar") 7 | assert_eq(buf.parent, "foobar") 8 | 9 | var buf2 = FileHandle.new_buf(:raw, "șk߀r§".encode_utf8) 10 | buf2.print("ășđkâß".encode_utf8) 11 | assert_eq(buf2.parent.decode_utf8, "șk߀r§ășđkâß") 12 | 13 | var buf3 = FileHandle.new_buf(:utf8, "șk߀r§") 14 | buf3.print("ășđkâß") 15 | assert_eq(buf3.parent.decode_utf8, "șk߀r§ășđkâß") 16 | 17 | say ":: Test passed!" 18 | -------------------------------------------------------------------------------- /scripts/Tests/find_the_missing_permutation.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func check_perm(arr) { 4 | (var hash = Hash.new){arr...} = +([1]*arr.len)... 5 | arr.each { |s| 6 | s.len.times { 7 | var t = (s.substr(1) + s.substr(0, 1)) 8 | hash.has_key(t) || return t; 9 | } 10 | } 11 | } 12 | 13 | var perms = %w(ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB DABC BCAD CADB CDBA 14 | CBAD ABDC ADBC BDCA DCBA BACD BADC BDAC CBDA DBCA DCAB); 15 | 16 | var missing_perm = check_perm(perms); 17 | assert_eq(missing_perm, 'DBAC'); 18 | 19 | say "** Test passed!"; 20 | -------------------------------------------------------------------------------- /scripts/Tests/first_class_functions_analogously.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/First-class_functions/Use_numbers_analogously 5 | # 6 | 7 | func multiplier(n1, n2) { 8 | func (n3) { 9 | n1 * n2 * n3; 10 | } 11 | } 12 | 13 | var x = 2.0; 14 | var xi = 0.5; 15 | var y = 4.0; 16 | var yi = 0.25; 17 | var z = (x + y); 18 | var zi = (1 / (x + y)); 19 | 20 | var numbers = [x, y, z]; 21 | var inverses = [xi, yi, zi]; 22 | 23 | [numbers, inverses].zip { |g,f| 24 | say multiplier(g, f)(0.5); 25 | } 26 | -------------------------------------------------------------------------------- /scripts/Tests/floyds_triangle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func floyd(rows, n=1) { 4 | var max = Math.range_sum(1, rows) 5 | var widths = (max-rows .. max-1 -> map{ .+ n -> len }) 6 | { |r| 7 | say %'#{1..r -> map{|i| "%#{widths[i-1]}d" % n++ }.join(" ")}' 8 | } << 1..rows 9 | } 10 | 11 | floyd(5, 88) 12 | -------------------------------------------------------------------------------- /scripts/Tests/for_two_vars.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Incrementing two vars in a 'for' loop 5 | # 6 | 7 | for ((var i = 0; var j = 3); i <= 5; (i++; j += i)) { 8 | "%d -- %d\n".printf(i, j); 9 | } 10 | -------------------------------------------------------------------------------- /scripts/Tests/forward_difference.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Forward_difference 5 | # 6 | 7 | func dif(arr) { 8 | gather { 9 | range(0, arr.end-1).each { |i| 10 | take(arr[i+1] - arr[i]); 11 | } 12 | } 13 | } 14 | 15 | func difn(n, arr) { 16 | n.times { arr = dif(arr) }; 17 | arr; 18 | } 19 | 20 | assert_eq(dif([1, 23, 45, 678]), [22, 22, 633]); 21 | assert_eq(difn(2, [1, 23, 45, 678]), [0, 611]); 22 | 23 | say "** Test passed!"; 24 | -------------------------------------------------------------------------------- /scripts/Tests/function_composition.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Functional_Composition 4 | 5 | func compose (f, g) { 6 | func(n){ f(g(n)) } 7 | } 8 | 9 | func f(n) { 10 | n / 64; 11 | } 12 | 13 | func g(n) { 14 | n * 32; 15 | } 16 | 17 | var fg = compose(f, g); # fg(x) is equivalent with: f(g(x)) 18 | 19 | assert_eq(fg(4), 2); 20 | say "** Test passed!"; 21 | -------------------------------------------------------------------------------- /scripts/Tests/functional_modules.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var spec = frequire('File::Spec::Functions'); 4 | "** This file: %s\n".printf(spec.catfile(spec.curdir, __FILE__)); 5 | "** Full path: %s\n".printf(spec.rel2abs(__FILE__)); 6 | 7 | # 8 | ## Same thing, but with a req check 9 | # 10 | 11 | var sf = ( 12 | try { frequire('File::Spec::Functions') } 13 | catch { nil } 14 | ); 15 | 16 | if (nil != sf) { 17 | "** Root dir: '%s'\n".printf(sf.rootdir); 18 | } 19 | 20 | __END__ 21 | var ron = frequire('Lingua::RO::Numbers'); 22 | var num = ron.number_to_ro(123553); 23 | 24 | num.say; 25 | -------------------------------------------------------------------------------- /scripts/Tests/gather_take.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # gather/take construct 4 | 5 | func fib(n) { 6 | var arr = gather { 7 | take(n <= 1 ? n : fib(n-1)+fib(n-2)); 8 | }; 9 | 10 | return arr[0]; 11 | } 12 | 13 | assert_eq(144, fib(12)); 14 | 15 | say "** Test passed!"; 16 | -------------------------------------------------------------------------------- /scripts/Tests/global_variables.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | global :a = (a => 1, b => 2) 4 | 5 | assert_eq(a, Hash(a => 1, b => 2)) 6 | 7 | assert_eq(a{:a}, 1) 8 | assert_eq(a{:b}, 2) 9 | 10 | global *b = (1,2,3) 11 | 12 | assert_eq(b, [1,2,3]) 13 | assert_eq(b[1], 2) 14 | 15 | func foo() { 16 | global xxx = 42 17 | } 18 | 19 | assert_eq(global xxx, nil) # not defined yet 20 | foo() # define xxx 21 | assert_eq(global xxx, 42) # should be defined 22 | assert_eq(xxx, 42) # also available in the current scope (after accessing it once with `global`) 23 | 24 | say "** Test passed!" 25 | -------------------------------------------------------------------------------- /scripts/Tests/goto.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Tests for the `goto` statement 4 | 5 | func example { 6 | 7 | var arr = [] 8 | 9 | goto :hello 10 | arr << "never here" 11 | 12 | @:hello 13 | arr << "hello" 14 | 15 | goto :world 16 | arr << "never here" 17 | 18 | @:world 19 | arr << "world" 20 | } 21 | 22 | assert_eq(example(), ['hello', 'world']) 23 | 24 | say "** Test passed!" 25 | -------------------------------------------------------------------------------- /scripts/Tests/group_precedence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | 4 + 2*3 + 2 == 12 ? ".".print : "Err1\n".die; 4 | 4+2*3+2 == 14 ? ".".print : "Err2\n".die; 5 | 4+2 * 3+2 == 30 ? ".".print : "Err3\n".die; 6 | 1+2*3 + 5*4 == 27 ? ".".print : "Err4\n".die; 7 | 1 + 2*3+4*5 == 47 ? ".".print : "Err5\n".die; 8 | 9 | "\nTest passed".say; 10 | -------------------------------------------------------------------------------- /scripts/Tests/hailstone.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Hailstone_sequence#Perl 4 | 5 | func hailstone (n) { 6 | 7 | var sequence = [n]; 8 | 9 | while (n > 1) { 10 | sequence.append( 11 | n.is_even ? n.div!(2) 12 | : n.mul!(3).add!(1) 13 | ); 14 | } 15 | 16 | return(sequence); 17 | } 18 | 19 | var h = hailstone(27); 20 | 21 | h[1] == 82 || "Item error!".die; 22 | h.len == 112 || "Length error!".die; 23 | 24 | "Length of hailstone(27) = %s".printlnf(h.len); 25 | "[%s]".printlnf(h.slice(0,5) + ['...'] + h.slice(-5) -> join(', ')); 26 | -------------------------------------------------------------------------------- /scripts/Tests/happy_2_years_old.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Happy birthday to Sidef 4 | # Date: 24th March 2015 5 | # Two years ago, the idea of Sidef was born, 6 | # but it got its actual name only 6 days later, 7 | # on 30th March 2013. 8 | 9 | class Singer(name="", age=0) { 10 | 11 | method sing { 12 | { 13 | say "Happy birthday #{name}!"; 14 | say "Happy birthday to you..."; 15 | } * 2; 16 | say "Happy #{age} years old!!!"; 17 | } 18 | } 19 | 20 | var s = Singer(name: "Sidef", age: 2); 21 | s.sing; 22 | 23 | assert_eq(s.name, "Sidef"); 24 | assert_eq(s.age, 2); 25 | -------------------------------------------------------------------------------- /scripts/Tests/hash_autovivification.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var v = Hash.new; 4 | 5 | v{:x} = 'y'; 6 | assert_eq(v{:x}, 'y'); 7 | 8 | v{:a}{:b}{:c} = 'd'; 9 | assert_eq(v{:a}{:b}{:c}, 'd'); 10 | 11 | v{:y}{:z} = Hash.new(a => 'b'); 12 | assert_eq(v{:y}{:z}{:a}, 'b'); 13 | 14 | 15 | v{:y}{:z}{:b} = 'c'; 16 | assert_eq(v{:y}{:z}{:b}, 'c'); 17 | 18 | say "** Test passed!"; 19 | -------------------------------------------------------------------------------- /scripts/Tests/hash_concat.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Hash.concat on various things, including non-hashes 5 | # 6 | 7 | var hash = Hash() 8 | hash += 1 9 | assert_eq(hash{"1"}, nil) 10 | 11 | hash += Hash(:a => :b) 12 | assert_eq(hash{:a}, :b) 13 | 14 | hash += %w(c d) # 2-item array 15 | assert_eq(hash{:c}, :d) 16 | 17 | hash += "2":3 # an actual Pair 18 | assert_eq(hash{"2"}, 3) 19 | 20 | say "** Test passed!" 21 | -------------------------------------------------------------------------------- /scripts/Tests/hash_from_array.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Creating an hash from two arrays 5 | # 6 | 7 | var keys = ["a", "b", "c"]; 8 | var vals = [1, 2, 3]; 9 | 10 | var hash = Hash(); 11 | hash{keys...} = vals...; # mapping keys and vals into hash 12 | 13 | assert_eq(hash{:a}, 1); 14 | assert_eq(hash{:c}, 3); 15 | 16 | assert_eq([hash{:a, :b}], [1,2]); 17 | assert_eq([hash{keys...}], vals); 18 | 19 | say "** Test passed!"; 20 | -------------------------------------------------------------------------------- /scripts/Tests/hash_grep.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var movie_ratings = :( 4 | 'memento' => 3, 5 | 'primer' => 3.5, 6 | 'the_matrix' => 3, 7 | 'truman_show' => 4, 8 | 'red_dawn' => 1.5, 9 | 'skyfall' => 4, 10 | 'alex_cross' => 2, 11 | 'uhf' => 1, 12 | 'lion_king' => 3.5, 13 | ); 14 | 15 | var good_movies = movie_ratings.grep { |_,v| v > 3 }; 16 | good_movies.dump.say; 17 | -------------------------------------------------------------------------------- /scripts/Tests/hash_sort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Sort a hash by its values (highest to lowest) 4 | 5 | var frequencies = Hash.new( 6 | "simple" => 2, 7 | "keep" => 4, 8 | "it" => 3, 9 | "stupid" => 1, 10 | ); 11 | 12 | # Traditional way 13 | var sorted_1 = frequencies.keys.sort({|a,b| frequencies{b} <=> frequencies{a}}).map({|key| [key, frequencies{key}]}); 14 | sorted_1.dump.say; 15 | 16 | # Built-in way 17 | var sorted_2 = frequencies.sort_by({|_,value| value}).reverse; 18 | sorted_2.dump.say; 19 | 20 | # The results should be identical 21 | sorted_2 == sorted_1 || "Error!\n".die; 22 | -------------------------------------------------------------------------------- /scripts/Tests/horner_s_rule.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Horner%27s_rule_for_polynomial_evaluation 4 | 5 | # 6 | ## Recursive 7 | # 8 | func horner_rec(coeff, x) { 9 | coeff.len > 0 ? ( 10 | coeff[0] + x*horner_rec(coeff.slice(1), x) 11 | ) : 0 12 | } 13 | 14 | assert_eq(128, horner_rec([-19, 7, -4, 6], 3)); 15 | 16 | # 17 | ## Functional 18 | # 19 | func horner_func(coeff, x) { 20 | coeff.reverse.reduce { |a,b| a*x + b }; 21 | } 22 | 23 | assert_eq(128, horner_func([-19.0, 7, -4, 6], 3)); 24 | 25 | say "** Test passed!"; 26 | -------------------------------------------------------------------------------- /scripts/Tests/hypot.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Tests for Number.hypot() and Complex.hypot() 4 | 5 | assert_eq(hypot( 3, 4), 5) 6 | assert_eq(hypot(-3, -4), 5) 7 | 8 | assert_eq("#{hypot( 3+4i, -2)}".first(7), '5.38516') 9 | assert_eq("#{hypot(-3-4i, -2)}".first(7), '5.38516') 10 | assert_eq("#{hypot(-3+4i, 2)}".first(7), '5.38516') 11 | 12 | assert_eq("#{hypot(3+4i, 5+23i)}".first(7), '24.0624') 13 | assert_eq("#{hypot(3+4i, -5-23i)}".first(7), '24.0624') 14 | assert_eq("#{hypot(3-4i, 5-23i)}".first(7), '24.0624') 15 | 16 | say "** Test passed!" 17 | -------------------------------------------------------------------------------- /scripts/Tests/i_love_you.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var Yes = null; 4 | 5 | { 6 | Yes.def_method(:I, func(self){class{method love{class{method you{say "Well, I hate you!"}}()}}()}); 7 | Yes -> I.love.you; 8 | }.run; 9 | -------------------------------------------------------------------------------- /scripts/Tests/infix_methods.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Test for infix methods 4 | 5 | var a = 42 6 | a `add!` 5 7 | assert_eq(a, 47) 8 | 9 | var b = (a `mul` 2) 10 | assert_eq(b, 94) 11 | assert_eq(a, 47) 12 | 13 | a `mul!` 2 `add!` 3 14 | assert_eq(a, 97) 15 | 16 | var c = (a `mul!` 2 `add` 3) 17 | 18 | assert_eq(a, 194) 19 | assert_eq(c, 197) 20 | 21 | var d = (a `add!` 5 `mul!` 2 `sub` 1) 22 | 23 | assert_eq(a, 398) 24 | assert_eq(d, 397) 25 | 26 | say "** Test passed!" 27 | -------------------------------------------------------------------------------- /scripts/Tests/integer_division.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Tests for the idiv* methods. 4 | 5 | for a in (-10..10), b in (-10..10) { 6 | 7 | next if (b == 0) 8 | 9 | assert_eq(round(a/b), idiv_round(a,b), "#{a}/#{b}") if !(a/b + 0.5 -> is_int) 10 | assert_eq(ceil(a/b), idiv_ceil(a,b), "#{a}/#{b}") 11 | assert_eq(floor(a/b), idiv_floor(a,b), "#{a}/#{b}") 12 | assert_eq(trunc(a/b), idiv_trunc(a,b), "#{a}/#{b}") 13 | 14 | assert_eq(floor(a/b + 1/2), idiv_round(a,b), "#{a}/#{b}") 15 | } 16 | 17 | say "** Test passed!" 18 | -------------------------------------------------------------------------------- /scripts/Tests/integer_limits.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Test the integer limits (32-bit and 64-bit) 5 | # 6 | 7 | var min32 = -2147483648 8 | var min64 = -9223372036854775808 9 | 10 | var max32 = 4294967295 11 | var max64 = 18446744073709551615 12 | 13 | assert_eq(max32 - 1, 4294967294) 14 | assert_eq(max64 - 1, 18446744073709551614) 15 | 16 | assert_eq(log2(max32+1), 32) 17 | assert_eq(log2(max64+1), 64) 18 | 19 | assert_eq(min64.abs.root(63), 2) 20 | assert_eq(min32.abs.root(31), 2) 21 | 22 | say "** Test passed!" 23 | -------------------------------------------------------------------------------- /scripts/Tests/interactive_mode_bug.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # The following code used to fail in interactive mode (fixed): 4 | # sidef -i interactive_mode_bug.sf 5 | 6 | func f(n) { sqrt(n) } 7 | func g(n) { f(n) + 42 } 8 | func h(n) { f(n) - 42 } 9 | 10 | for n in (1..5) { 11 | say g(n) 12 | say h(n) 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/irootrem.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var range = (1 .. 50 -> by(irand(1, 15))) 4 | 5 | for k in range { 6 | for j in range { 7 | 8 | var (x, y) = k.irootrem(j) 9 | var r = k.iroot(j) 10 | var m = (k - r.ipow(j)) 11 | 12 | #say "#{k} #{j} (#{x}, #{y}) (#{r}, #{m})" 13 | 14 | assert_eq("#{x}", "#{r}") 15 | assert_eq("#{y}", "#{m}") 16 | 17 | if (x.is_pos) { 18 | var r = k.root(j).int 19 | assert_eq("#{x}", "#{r}") 20 | assert_eq("#{y}", "#{k - r**j}") 21 | } 22 | } 23 | } 24 | 25 | say "** Test passed!" 26 | -------------------------------------------------------------------------------- /scripts/Tests/is_power.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Test the built-in method `is_pow`; 4 | # And also test `iroot` and `ipow`; 5 | 6 | func is_power(n, k) { 7 | n.iroot(k).ipow(k) == n 8 | } 9 | 10 | for i in (-100 .. 100) { 11 | say "3: #{i}" if is_power(i, 3) 12 | say "4: #{i}" if is_power(i, 4) 13 | 14 | if (is_power(i, 3) != i.is_pow(3)) { 15 | die "error is_power(#{i}, 3)" 16 | } 17 | 18 | if (is_power(i, 4) != i.is_pow(4)) { 19 | die "error is_power(#{i}, 4)" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scripts/Tests/is_prime.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func is_prime(Number _ (2)) { true } 4 | func is_prime(Number _ { _ <= 1 || !(_ & 1)}) { false } 5 | func is_prime(Number a) { range(3, a.isqrt) -> any { a %% _ } -> not } 6 | 7 | assert_eq( 8 | (0..50).grep { is_prime(_) }, 9 | [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] 10 | ) 11 | 12 | say "** Test passed!"; 13 | -------------------------------------------------------------------------------- /scripts/Tests/leap_year.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func leap (year) { 4 | year % 100 == 0 5 | ? (year % 400 == 0) 6 | : (year % 4 == 0); 7 | }; 8 | 9 | range(2000, 2013).each { |i| 10 | (leap(i) 11 | ? "%d was a leap year\n" 12 | : "%d wasn't a leap year\n" 13 | ).printf(i); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/Tests/lev_fast.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Levenshtein_distance#Sidef 4 | 5 | func lev(s, t) { 6 | var d = [@(0 .. t.len), s.len.of {[_]}...] 7 | for i,j in (^s ~X ^t) { 8 | d[i+1][j+1] = ( 9 | s[i] == t[j] 10 | ? d[i][j] 11 | : 1+Math.min(d[i][j+1], d[i+1][j], d[i][j]) 12 | ) 13 | } 14 | d[-1][-1] 15 | } 16 | 17 | assert_eq(lev(%c'kitten', %c'sitting'), 3) 18 | assert_eq(lev(%c'rosettacode', %c'raisethysword'), 8) 19 | 20 | say "** Test passed!"; 21 | -------------------------------------------------------------------------------- /scripts/Tests/lingua_ro_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include Lingua::RO::Numbers; 4 | var lingua = Lingua::RO::Numbers::new(); 5 | 6 | lingua.thousands_separator = (','); 7 | 8 | for(var i = -1000000; i <= 1000000; i += 500000.irand) { 9 | 10 | # From number to RO 11 | var ro = lingua.number_to_ro(i); 12 | 13 | # From RO to number 14 | var num = lingua.ro_to_number(ro); 15 | 16 | # Print the results 17 | "%-10s%-10s%s\n".printf(i, num, ro); 18 | 19 | # Check the results 20 | if (i != num) { 21 | "Error: #{num} != #{i}\n".die; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/Tests/longest_common_subsequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Longest_common_subsequence#Sidef 5 | # 6 | 7 | func lcs(String xstr, String ystr) is cached -> String { 8 | (xstr.is_empty || ystr.is_empty) && return ''; 9 | 10 | var(x, xs, y, ys) = (xstr.first, xstr.slice(1), 11 | ystr.first, ystr.slice(1)); 12 | 13 | if (x == y) { 14 | x + lcs(xs, ys) 15 | } else { 16 | [lcs(xstr, ys), lcs(xs, ystr)].max_by {|x| x.len }; 17 | } 18 | } 19 | 20 | assert_eq(lcs("thisisatest", "testing123testing"), "tsitest"); 21 | 22 | say "** Test passed!"; 23 | -------------------------------------------------------------------------------- /scripts/Tests/magic_vars.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | local $, = "\n"; # sets the list separator to "\n" 4 | say ("hello", "world"); # prints one item per line 5 | 6 | if (Sys.open(\var fh, '<:encoding(UTF-8)', Sys.sidef)) { 7 | 8 | var lines = 1+(10.rand.int); 9 | say "\n** Reading ##{lines} lines from `#{fh.parent}':"; 10 | 11 | fh.each { |line| 12 | say line.chomp; 13 | Number.new($.) == lines && break; 14 | }; 15 | 16 | Number.new($.) == lines || ( 17 | "#{$.} != #{lines}!".die; 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /scripts/Tests/man_or_boy.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func a(k, x1, x2, x3, x4, x5) { 4 | func b { a(--k, b, x1, x2, x3, x4) }; 5 | k <= 0 ? (x4() + x5()) : b(); 6 | } 7 | 8 | assert_eq(a(10, ->{1}, ->{-1}, ->{-1}, ->{1}, ->{0}), -67); 9 | 10 | say "** Test passed!"; 11 | -------------------------------------------------------------------------------- /scripts/Tests/man_or_boy_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func a(k, x1, x2, x3, x4, x5) { 4 | k <= 0 ? (x4() + x5()) 5 | : func b { a(--k, b, x1, x2, x3, x4) }(); 6 | }; 7 | 8 | assert_eq(a(10, {1}, {-1}, {-1}, {1}, {0}), -67); 9 | 10 | say "** Test passed!"; 11 | -------------------------------------------------------------------------------- /scripts/Tests/man_or_boy_3.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class Test { 4 | method a(k, x1, x2, x3, x4, x5) { 5 | func b { self.a(--k, b, x1, x2, x3, x4) }; 6 | k <= 0 ? (x4.run + x5.run) : b(); 7 | } 8 | } 9 | 10 | var obj = Test(); 11 | assert_eq(obj.a(10, {1}, {-1}, {-1}, {1}, {0}), -67); 12 | 13 | say "** Test passed!"; 14 | -------------------------------------------------------------------------------- /scripts/Tests/man_or_boy_cached.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func a(k, x1, x2, x3, x4, x5) is cached -> Number { 4 | func b() -> Number { a(--k, b, x1, x2, x3, x4) }; 5 | k <= 0 ? (x4.run + x5.run) : b(); 6 | } 7 | 8 | assert_eq(a(10, {1}, {-1}, {-1}, {1}, {0}), -67); 9 | 10 | say "** Test passed!"; 11 | -------------------------------------------------------------------------------- /scripts/Tests/median.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func median(c) { 4 | var a = c.sort{|a,b| a <=> b}; 5 | a[a.end/2] + a[a.len/2] / 2; 6 | } 7 | 8 | "Median: %s\n".printf(median([ 9 | 28.207, 10 | 74.916, 11 | 51.694, 12 | 72.486, 13 | 58.306, 14 | 32.421, 15 | 10.801, 16 | 73.807, 17 | ])); 18 | -------------------------------------------------------------------------------- /scripts/Tests/method_aliases.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Example of method aliases 5 | # 6 | 7 | class Hi { 8 | method hi { 9 | say "Hello!"; 10 | }; 11 | 12 | Hi.alias_method(hi => :hello); 13 | Hi.alias_method(hello => :hey); 14 | } 15 | 16 | var obj = Hi(); 17 | 18 | obj.hi; 19 | obj.hello; 20 | obj.hey; 21 | 22 | # 23 | ## Alias of built-in methods 24 | # 25 | String.alias_method(uc => :in_litere_mari); 26 | say "Hello!".in_litere_mari; 27 | -------------------------------------------------------------------------------- /scripts/Tests/method_expressions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var method = 'sqrt'; 4 | 81->$method.to_s.say; 5 | 6 | 42->(['+','-'][2.rand])(10).to_s.say; 7 | -------------------------------------------------------------------------------- /scripts/Tests/module_identifiers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include Module::Test 4 | 5 | func f(n < Module::Test::foo) { 6 | 2*n 7 | } 8 | 9 | assert_eq(f(21), 42) 10 | 11 | var t = Module::Test::Bar("hello", 42) 12 | 13 | assert_eq(t.a, "hello") 14 | assert_eq(t.b, 42) 15 | 16 | import Module::Test::Bar 17 | 18 | var t2 = Bar(42, "foo") 19 | 20 | assert_eq(t2.a, 42) 21 | assert_eq(t2.b, "foo") 22 | 23 | do { 24 | var ok = false 25 | 26 | try { 27 | Bar([], {}) 28 | } 29 | catch { 30 | ok = true 31 | } 32 | 33 | assert(ok) 34 | } 35 | 36 | say "** Test passed!" 37 | -------------------------------------------------------------------------------- /scripts/Tests/module_inclusion_3.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Module inclusion 5 | # 6 | 7 | module Foo { 8 | var uuu = 99 9 | module Bar { 10 | var vvv = 42 11 | } 12 | } 13 | 14 | module Baz { 15 | include Foo 16 | assert_eq(Foo::uuu, 99) 17 | assert_eq(Bar::vvv, 42) 18 | } 19 | 20 | module Zero { 21 | include Foo 22 | assert_eq(Bar::vvv, 42) 23 | assert_eq(Foo::uuu, 99) 24 | } 25 | 26 | assert_eq(Bar::vvv, 42) 27 | assert_eq(Foo::uuu, 99) 28 | 29 | say "** Test passed!" 30 | -------------------------------------------------------------------------------- /scripts/Tests/module_loading.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | include Module::Fib; 4 | include Module::Fact; 5 | 6 | Module::Fib::fibonacci(10) == 55 || die "error fib"; 7 | Module::Fact::factorial(4) == 24 || die "error fact"; 8 | 9 | include Module::YouTube; 10 | 11 | var youtube_url = "abcdef".as_youtube_url; 12 | assert(youtube_url.begins_with("http")); 13 | 14 | include Module::Foo; 15 | include Module::Bar; 16 | 17 | var foo = Module::Foo::Bar(); 18 | var bar = Module::Bar::Bar(); 19 | 20 | assert_eq(foo.baz, 'foo'); 21 | assert_eq(bar.baz, 'bar'); 22 | 23 | say "** Test passed!"; 24 | -------------------------------------------------------------------------------- /scripts/Tests/modules_simple_test.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var bar = "this is bar" 4 | 5 | module Foo { 6 | var x = 42 7 | var y = 99 8 | 9 | assert_eq(main::bar, "this is bar") 10 | assert_eq(x, 42) 11 | assert_eq(y, 99) 12 | } 13 | 14 | assert_eq(bar, "this is bar") 15 | assert_eq(main::bar, "this is bar") 16 | assert_eq(Foo::x, 42) 17 | assert_eq(Foo::y, 99) 18 | 19 | say "** Test passed!" 20 | -------------------------------------------------------------------------------- /scripts/Tests/modules_test_1.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | module Bar { 4 | class Foo { 5 | method test { 6 | "reached" 7 | } 8 | } 9 | } 10 | 11 | module Zero { 12 | var hi = 'hi' 13 | } 14 | 15 | var obj = Bar::Foo() 16 | 17 | assert_eq(obj.test, "reached") 18 | assert_eq(Zero::hi, "hi") 19 | 20 | say "** Test passed!" 21 | -------------------------------------------------------------------------------- /scripts/Tests/modules_test_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var foo = 42 4 | 5 | module Bar { 6 | import main::foo 7 | var baz = 2*foo 8 | } 9 | 10 | import Bar::baz 11 | assert_eq(baz, 84) 12 | 13 | say "** Test passed!" 14 | -------------------------------------------------------------------------------- /scripts/Tests/multi_file_edit.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var files = %w( 4 | a.txt 5 | b.txt 6 | c.txt 7 | ).map{.to_file}; 8 | 9 | files.each { |file| 10 | say file.edit { |line| 11 | line.gsub("Goodbye London!", "Hello New York!"); 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/multi_var_assignment.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var (x, y) = ("here", "there".uc); 4 | 5 | x == "here" || ("x error!".die); 6 | y == "THERE" || ("y error!".die); 7 | 8 | "x is " + x -> say; 9 | "y is " + y -> say; 10 | -------------------------------------------------------------------------------- /scripts/Tests/multisplit.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Multisplit#Sidef 5 | # 6 | 7 | func multisplit(sep, str, :opt) { 8 | sep = sep.map{.escape}.join('|'); 9 | var re = Regex.new(opt{:keep_sep} ? "(#{sep})" : sep); 10 | str.split(re, -1); 11 | } 12 | 13 | var chunks = []; 14 | [false, true].each { |bool| 15 | chunks.append(multisplit(%w(== != =), 'a!===b=!=c!=', keep_sep => bool)); 16 | } 17 | 18 | assert_eq(chunks, 19 | [ 20 | ["a", "", "b", "", "c", ""], 21 | ["a", "!=", "", "==", "b", "=", "", "!=", "c", "!=", ""], 22 | ]); 23 | 24 | say "** Test passed!"; 25 | -------------------------------------------------------------------------------- /scripts/Tests/named_block_arguments.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var arr = (1..10 -> map{10.irand}); 4 | var arc = (arr.map{|i|i}); 5 | 6 | arr.grep {|n| n > 3} == ( 7 | arr.grep { _ > 3 } 8 | ) || die "grep error" 9 | 10 | arr.map {|x| x + 3} == ( 11 | arr.map { _ + 3} 12 | ) || die "map error" 13 | 14 | { 15 | |x,y| 16 | x+y 17 | }.call(10,32) == 42 || 18 | die "block error" 19 | 20 | arc == arr || 21 | die "arr modified in place" 22 | 23 | say "** Test passed!"; 24 | -------------------------------------------------------------------------------- /scripts/Tests/object_copy.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class T(value) { 4 | method display { 5 | say value; 6 | } 7 | } 8 | 9 | class S(value) < T { 10 | method display { 11 | say value; 12 | } 13 | } 14 | 15 | var obj1 = T("T"); 16 | var obj2 = S("S"); 17 | var obj3 = obj2.dclone; # make a deep clone of obj2 18 | 19 | obj2.value = "foo"; # change the value of obj2 20 | 21 | assert_eq(obj1.value, "T"); 22 | assert_eq(obj2.value, "foo"); 23 | assert_eq(obj3.value, "S"); 24 | 25 | obj1.display; 26 | obj2.display; 27 | obj3.display; 28 | -------------------------------------------------------------------------------- /scripts/Tests/one-dimensional_cellular_automata.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/One-dimensional_cellular_automata 5 | # 6 | 7 | var seq = "_###_##_#_#_#_#__#__"; 8 | var x = ''; 9 | 10 | loop { 11 | seq.tr!('01', '_#'); 12 | say seq; 13 | seq.tr!('_#', '01'); 14 | seq.gsub!(/(?<=(.))(.)(?=(.))/, {|s1,s2,s3| s1 == s3 ? (s1 ? (1 - s2.to_i) : 0) : s2}); 15 | (x != seq) && (x = seq) || break; 16 | }; 17 | -------------------------------------------------------------------------------- /scripts/Tests/open.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var file = File(__FILE__) 4 | 5 | if (file.open_r(\var fh)) { 6 | say "** File successfully accessed!"; 7 | 8 | fh.readline == "#!/usr/bin/ruby" || 9 | die "fh.readline error!\n"; 10 | } 11 | else { 12 | die "Can't open the file for reading!\n"; 13 | } 14 | -------------------------------------------------------------------------------- /scripts/Tests/pair_namedparam_force_ops.sf: -------------------------------------------------------------------------------- 1 | #! /usr/bin/ruby 2 | 3 | var f = :name 4 | assert_eq(f⫶ 1 -> dump, name: 1 -> dump) 5 | assert_eq(f⫶ 1 -> dump, (f)⫶ 1 -> dump) 6 | assert_eq((f)⫶ 1 -> dump, name: 1 -> dump) 7 | assert_eq(:a⫶ 1 -> dump, a:1 -> dump) 8 | 9 | var n = 1 10 | 11 | assert_ne(n: 2 -> dump, (n): 2 -> dump) 12 | assert_eq((n): 2 -> dump, 1: 2 -> dump) 13 | assert_eq(n:2, Pair(1, 2)) 14 | assert_eq(1:2, 1+2i) 15 | assert_eq(1:2, Pair(1, 2)) 16 | 17 | say "** Test passed!" 18 | -------------------------------------------------------------------------------- /scripts/Tests/pairs_test.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## This script is used for testing only 5 | # 6 | 7 | var tree = 'root':'child':'grandchild':'end'; 8 | 9 | while (true) { 10 | say tree.first; 11 | tree.second.is_a(Pair) || break; 12 | tree = tree.second; 13 | } 14 | 15 | say( 16 | Pair.new('root', 17 | Pair.new('child', 18 | Pair.new('grandchild', 'end') 19 | ) 20 | ) 21 | ) 22 | -------------------------------------------------------------------------------- /scripts/Tests/palindrome_detection_recursive.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # https://rosettacode.org/wiki/Palindrome_detection#Sidef 4 | 5 | func palindrome(s) { 6 | if (s.len <= 1) { 7 | true 8 | } 9 | elsif (s.char_at(0) != s.char_at(-1)) { 10 | false 11 | } 12 | else { 13 | __FUNC__(s.substr(1, -1)) 14 | } 15 | } 16 | 17 | var str = 'In girum imus nocte et consumimur igni'; 18 | 19 | palindrome(str.lc - /\s+/g) || die "error!"; 20 | palindrome('sidef') && die "error!"; 21 | palindrome('salàlas') || die "error!"; 22 | 23 | say "** Test passed!"; 24 | -------------------------------------------------------------------------------- /scripts/Tests/pcg.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of M.E. O'Neill's C code: 4 | # https://www.pcg-random.org/download.html 5 | 6 | struct PCG32 { 7 | Number state, 8 | Number inc, 9 | } 10 | 11 | func pcg32(rng) { 12 | var oldstate = rng.state 13 | rng.state = (oldstate * 6364136223846793005 + (rng.inc | 1)) 14 | var xorshifted = (((oldstate >> 18) ^ oldstate) >> 27) 15 | var rot = (oldstate >> 59) 16 | (xorshifted >> (rot & 31)) | (xorshifted << ((-rot) & 31)) 17 | } 18 | 19 | var rng = PCG32(42, 3) 20 | say 10.of { pcg32(rng) } 21 | -------------------------------------------------------------------------------- /scripts/Tests/perfect_root_power.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for n in (-100 .. 100) { 4 | var r = perfect_root(n) 5 | var k = perfect_power(n) 6 | 7 | if (r**k != n) { 8 | die "error for: #{n}" 9 | } 10 | } 11 | 12 | say "** Test passed!" 13 | -------------------------------------------------------------------------------- /scripts/Tests/permutations.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Permutations 5 | # 6 | 7 | func permute (code, arr) { 8 | var idx = arr.keys; 9 | 10 | while (true) { 11 | code(arr.items(idx...)); 12 | 13 | var p = idx.end; 14 | while (idx[p - 1] > idx[p]) { --p }; 15 | p == 0 && return(); 16 | 17 | idx += idx.splice(p).reverse; 18 | 19 | var d = p; 20 | while (idx[p - 1] > idx[d]) { ++d }; 21 | idx[p-1, d] = idx[d, p-1]; 22 | } 23 | } 24 | 25 | var name = %c"abc"; 26 | permute(func (list) { list.join(' ').say }, name); 27 | -------------------------------------------------------------------------------- /scripts/Tests/permutations_2.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Permutations 5 | # 6 | 7 | func permutations(callback, set, perm=[]) { 8 | set.len == 0 && callback(perm); 9 | for i in range(set.len) { 10 | __FUNC__(callback, [set[(0 ..^ i)..., (i+1 ..^ set.len)...]], [perm..., set[i]]); 11 | } 12 | }; 13 | 14 | var list = [1,2,3]; 15 | permutations({|set| say set.join}, list); 16 | -------------------------------------------------------------------------------- /scripts/Tests/pi_and_e.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func pi(n) { 4 | var pi = 0.0; 5 | 6 | for ((var i = 1; var j = 0) ; j <= n ; (i += 2; j++)) { 7 | pi += (1/i -> (%w(neg abs)[j.is_even])); 8 | } 9 | 10 | return (pi * 4); 11 | } 12 | 13 | func e(n) { 14 | var e = 1.0; 15 | 16 | for (1..n) { |i| 17 | e += (1 / i.factorial); 18 | } 19 | 20 | return e; 21 | } 22 | 23 | 24 | say pi(120); 25 | say e(10); 26 | -------------------------------------------------------------------------------- /scripts/Tests/pi_machin_like_formula.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## See: https://en.wikipedia.org/wiki/Machin-like_formula 5 | # 6 | 7 | # After 黃見利 (Hwang Chien-Lih) (1997) 8 | 9 | say( 10 | 4 * ( 11 | (183 * atan2(1, 239)) + 12 | ( 32 * atan2(1, 1023)) - 13 | ( 68 * atan2(1, 5832)) + 14 | ( 12 * atan2(1, 110443)) - 15 | ( 12 * atan2(1, 4841182)) - 16 | (100 * atan2(1, 6826318)) 17 | ) 18 | ); 19 | 20 | 21 | say Num.pi; 22 | -------------------------------------------------------------------------------- /scripts/Tests/pipeline_cross_operator.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func increment(n,a) { n+a } 4 | 5 | assert_eq( 6 | [100, 10000, 1000000] |X> (:sqrt, [increment, 2]), 7 | [10, 102, 100, 10002, 1000, 1000002] 8 | ) 9 | 10 | assert_eq([1,2,3] |X> { _*2 } , [2, 4, 6]) 11 | assert_eq([1,2,3] |X> [:mul, 2], [2, 4, 6]) 12 | 13 | assert_eq([3,4] |X> (:ipow2, :ipow10), [8, 1000, 16, 10000]) 14 | 15 | say "** Test passed!" 16 | -------------------------------------------------------------------------------- /scripts/Tests/pipeline_map_operator.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | assert_eq([25,36,49] |>> :log |>> :exp |>> :sqrt |>> :round, [5, 6, 7]) 4 | 5 | func square(n) { n*n } 6 | 7 | assert_eq([3,4,5] |>> square, [9, 16, 25]) 8 | assert_eq([3,4,5] |>> {_*_}, [9, 16, 25]) 9 | 10 | assert_eq([3,4,5] |>> square |>> :sqrt, [3,4,5]) 11 | assert_eq([3,4,5] |>> square |>> {.sqrt}, [3,4,5]) 12 | assert_eq([3,4,5] |>> [:pow, 2] |>> {.sqrt}, [3,4,5]) 13 | assert_eq([3,4,5] |>> [:pow, 2] |>> :sqrt, [3,4,5]) 14 | 15 | assert_eq([1,2,3] |>> (:ipow, 2), [1, 4, 9]) 16 | assert_eq([1,2,3] |>> [:ipow, 2], [1, 4, 9]) 17 | 18 | say "** Test passed!" 19 | -------------------------------------------------------------------------------- /scripts/Tests/polynomial_regression.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func regress(x, y, degree) { 4 | var A = Matrix.build(x.len, degree+1, {|i,j| 5 | x[i]**j 6 | }) 7 | 8 | var B = Matrix.column_vector(y...) 9 | ~((~A * A)**(-1) * ~A * B) 10 | } 11 | 12 | func poly(x) { 13 | 3*x**2 + 2*x + 1 14 | } 15 | 16 | var coeff = regress( 17 | 10.of { _ }, 18 | 10.of { poly(_) }, 19 | 2 20 | ) 21 | 22 | assert_eq(coeff, [[1,2,3]]) 23 | 24 | say "** Test passed!" 25 | -------------------------------------------------------------------------------- /scripts/Tests/postfix_exclamation_mark.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Test the `!` and `!!` postfix operators. 4 | 5 | class Example { 6 | method ! { 7 | "single" 8 | } 9 | 10 | method !! { 11 | "double" 12 | } 13 | } 14 | 15 | var obj = Example() 16 | 17 | assert_eq(obj!, 'single') 18 | assert_eq(obj!!, 'double') 19 | 20 | var k = obj! 21 | var j = obj!! 22 | 23 | assert_eq(k, 'single') 24 | assert_eq(j, 'double') 25 | 26 | assert_eq((2*5)!, 3628800) 27 | assert_eq((2*5)!!, 3840) 28 | 29 | say "** Test passed!" 30 | -------------------------------------------------------------------------------- /scripts/Tests/power_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for (1..15) { |i| 4 | var pow = (1 << (i-1) / i); 5 | 6 | var num = (i**i); 7 | {num=(num.sqrt)} * (i-1); 8 | 9 | "%3.0f\t%s\n".printf(num**pow, pow); 10 | } 11 | -------------------------------------------------------------------------------- /scripts/Tests/prefix_methods.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Tests for prefix methods 4 | 5 | var i = int(12.5); 6 | 7 | assert_eq(i, 12); 8 | assert_eq(lc("TeSt"), "test"); 9 | assert_eq(ceil(12.1.add(2)), 15); 10 | 11 | var int = 42; 12 | assert_eq(int, 42); 13 | assert_eq(::int(12.5), 12); # `::` solves the ambiguity 14 | 15 | var l1 = lcm([3,4]...) 16 | assert_eq(l1, 12) 17 | 18 | var l2 = ::lcm [3,4]... 19 | assert_eq(l2, 12) 20 | 21 | say "** Test passed!"; 22 | -------------------------------------------------------------------------------- /scripts/Tests/pythagorean_means.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Averages/Pythagorean_means#Perl_6 4 | 5 | func A(a) { a«+» / a.len } 6 | func G(a) { a«*» ** 1/a.len } 7 | func H(a) { a «/« 1 «+» / a.len ** -1 } 8 | 9 | var ints = @(1..10) 10 | say("A(1,...,10) = ", A(ints)) 11 | say("G(1,...,10) = ", G(ints)) 12 | say("H(1,...,10) = ", H(ints)) 13 | 14 | assert_eq(A(ints), 11/2) 15 | assert_eq(G(ints), ints.prod.root(ints.len)) 16 | assert_eq(H(ints), 25200/7381) 17 | -------------------------------------------------------------------------------- /scripts/Tests/quicksort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Perl 4 | 5 | func quicksort (a) { 6 | a.len < 2 && return(a); 7 | var p = a.pop_rand; # to avoid the worst cases 8 | __FUNC__(a.grep{ .< p}) + [p] + __FUNC__(a.grep{ .>= p}); 9 | } 10 | 11 | var a = [4, 65, 2, -31, 0, 99, 83, 782, 2, 0, 1].shuffle; 12 | var s = quicksort(a.clone); 13 | 14 | say "Unsorted #{a.dump}"; 15 | say "Sorted #{s.dump}"; 16 | 17 | a.sort == s || die "The array is not sorted!"; 18 | -------------------------------------------------------------------------------- /scripts/Tests/range_prod.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for i in (1..10) { 4 | var r = RangeNum(1, 100.irand, 1) 5 | 6 | var p1 = Math.prod(r...) 7 | var p2 = r.prod 8 | 9 | if (p1 != p2) { 10 | die "error: #{r} -> #{p1} != #{p2}\n"; 11 | } 12 | } 13 | 14 | say "** Test passed!" 15 | -------------------------------------------------------------------------------- /scripts/Tests/range_sum.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for i in (1..10) { 4 | var r = RangeNum(100.irand, 100.irand, 1) 5 | 6 | var s1 = Math.sum(r...) 7 | var s2 = r.sum 8 | 9 | if (s1 != s2) { 10 | die "error: #{r} -> #{s1} != #{s2}\n"; 11 | } 12 | } 13 | 14 | say "** Test passed!" 15 | -------------------------------------------------------------------------------- /scripts/Tests/rec_reverse.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func rec_reverse(array, code) { 4 | var len = array.len; 5 | 6 | len == 0 && return(); 7 | len == 1 && return code.call(array[0]); 8 | 9 | var chunks = array/2; 10 | __FUNC__(chunks[1], code); 11 | __FUNC__(chunks[0], code); 12 | } 13 | 14 | rec_reverse("fediS".split(1), {|c| say c}); 15 | -------------------------------------------------------------------------------- /scripts/Tests/recursive_block_closures.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Test the `__BLOCK__` keyword. 4 | 5 | var closures = 5.of { |k| 6 | { |n| 7 | n <= 1 ? n : (k * (__BLOCK__(n-1) + __BLOCK__(n-2))) 8 | } 9 | } 10 | 11 | assert_eq(closures[0](10), 0) 12 | assert_eq(closures[1](10), 55) 13 | assert_eq(closures[3](10), 133893) 14 | assert_eq(closures[2](10), 6688) 15 | assert_eq(closures[1](12), 144) 16 | 17 | say "** Test passed!" 18 | -------------------------------------------------------------------------------- /scripts/Tests/regex_bool.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var str = 'hello'; 4 | var re = ('^'+str+'\h+(?i:world)\z' -> to_regex); 5 | 6 | if (!'hello WoRlD'.match(re)) { 7 | "Regex didn't matched!\n".die; 8 | } 9 | 10 | if('Hell WoRlD' =~ re) { 11 | "Regex shouldn't match!\n".die; 12 | } 13 | 14 | say "Test passed!"; 15 | -------------------------------------------------------------------------------- /scripts/Tests/regex_match_as_array.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var m = /(\w+)\s+(\w+)/.match("foo bar"); 4 | 5 | assert_eq(m[0], 'foo'); 6 | assert_eq(m[1], 'bar'); 7 | 8 | say "** Test passed!"; 9 | -------------------------------------------------------------------------------- /scripts/Tests/roman_numerals_decoding_3.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func roman2arabic(digit) { 4 | digit.uc.trans([ 5 | 'M': '1000+', 6 | 'CM': '900+', 7 | 'D': '500+', 8 | 'CD': '400+', 9 | 'C': '100+', 10 | 'XC': '90+', 11 | 'L': '50+', 12 | 'XL': '40+', 13 | 'X': '10+', 14 | 'IX': '9+', 15 | 'V': '5+', 16 | 'IV': '4+', 17 | 'I': '1+', 18 | ]).split('+').map{.to_i}.sum; 19 | } 20 | 21 | %w(MCMXC MMVIII MDCLXVI).each { |roman_num| 22 | say "#{roman_num}\t-> #{roman2arabic(roman_num)}"; 23 | } 24 | -------------------------------------------------------------------------------- /scripts/Tests/root_mean_square.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Translation of: https://rosettacode.org/wiki/Averages/Root_mean_square#Perl_6 4 | 5 | func rms (a) { 6 | a.map{_**2} -> sum / a.len -> sqrt; 7 | } 8 | 9 | println(rms(1..10)); 10 | -------------------------------------------------------------------------------- /scripts/Tests/sidef_keywords.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var hash = Perl.to_sidef(Parser{:keywords}); 4 | 5 | var keys = hash.keys.sort; 6 | var max = keys.map{.len}.max; 7 | 8 | var cols = 3; 9 | 0 ..^ (keys.end, cols) -> each { |i| 10 | %(#{"%-#{max+2}s" * cols-1}%s\n) -> printf(keys[i .. (i + cols-1) -> ...]); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/Tests/sierpinski_carpet.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var c = ['##']; 4 | 5 | { 6 | c = ( c.map{.*3} + c.map{|l| l + (' ' * l.len) + l } + c.map{.*3} ); 7 | } * 3; 8 | 9 | c.join("\n").say; 10 | -------------------------------------------------------------------------------- /scripts/Tests/sierpinski_diamond.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func sierpinski_diamond(n) { 4 | var triangle = ['*']; 5 | { |i| 6 | var sp = (' ' * 2**i); 7 | triangle = (triangle.map {|x| sp + x + sp } + 8 | triangle.map {|x| x + ' ' + x } + 9 | triangle.map {|x| sp + x + sp} ); 10 | } * n; 11 | triangle.join("\n"); 12 | } 13 | 14 | say sierpinski_diamond(2); 15 | -------------------------------------------------------------------------------- /scripts/Tests/sierpinski_penta.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func sierpinski_penta(n) { 4 | var penta = ['*']; 5 | { |i| 6 | var sp = (' ' * 2**i); 7 | penta = ( 8 | penta.map {|x| sp + x + ' ' + x + sp} + 9 | penta.map {|x| x + sp + ' ' + sp + x} + 10 | penta.map {|x| sp*2 + ' '*(i**2) + x + ' '*(i**2) + sp*2} 11 | ); 12 | } * n; 13 | penta.join("\n"); 14 | } 15 | 16 | say sierpinski_penta(3); 17 | -------------------------------------------------------------------------------- /scripts/Tests/sierpinski_triangle_90.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 90-degree version of Sierpinski's triangle 4 | # https://rosettacode.org/wiki/Sierpinski_triangle 5 | 6 | func sierpinski_triangle_90(n) { 7 | var triangle = ['*']; 8 | { |i| 9 | var sp = (' ' * 2**i); 10 | triangle = (triangle.map {|x| x + sp*2} + 11 | triangle.map {|x| x + ' ' + x}); 12 | } * n; 13 | triangle.join("\n"); 14 | } 15 | 16 | say sierpinski_triangle_90(4); 17 | -------------------------------------------------------------------------------- /scripts/Tests/sierpinski_x.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func sierpinski_x(n) { 4 | var triangle = ['*']; 5 | { 6 | triangle = (triangle.map {|x| x + ' '*(x.len) + x } + 7 | triangle.map {|x| ' '*(x.len) + x + ' '*(x.len) } + 8 | triangle.map {|x| x + ' '*(x.len) + x} ); 9 | } * n; 10 | triangle.join("\n"); 11 | } 12 | 13 | say sierpinski_x(3); 14 | -------------------------------------------------------------------------------- /scripts/Tests/slurpy_define.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | do { 4 | define ( 5 | *a = (1,2,3), 6 | :b = (a => 1, b => 2), 7 | ) 8 | 9 | assert_eq(a, [1,2,3]) 10 | assert_eq(b, Hash(a => 1, b => 2)) 11 | 12 | a[0] = 99 13 | b{:b} = 42 14 | 15 | assert_eq(a, [99, 2, 3]) 16 | assert_eq(b, Hash(a => 1, b => 42)) 17 | 18 | define foo = (42, 99) 19 | assert_eq(foo, 42) 20 | } 21 | 22 | do { 23 | define(foo = 42, bar = foo+2) 24 | 25 | assert_eq(foo, 42) 26 | assert_eq(bar, 44) 27 | } 28 | 29 | say "** Test passed!" 30 | -------------------------------------------------------------------------------- /scripts/Tests/slurpy_static.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | do { 4 | static ( 5 | *a = (1,2,3), 6 | :b = (a => 1, b => 2), 7 | ) 8 | 9 | assert_eq(a, [1,2,3]) 10 | assert_eq(b, Hash(a => 1, b => 2)) 11 | 12 | a[0] = 99 13 | b{:b} = 42 14 | 15 | assert_eq(a, [99, 2, 3]) 16 | assert_eq(b, Hash(a => 1, b => 42)) 17 | 18 | static foo = (42, 99) 19 | assert_eq(foo, 42) 20 | } 21 | 22 | do { 23 | static(foo = 42, bar = foo+2) 24 | 25 | assert_eq(foo, 42) 26 | assert_eq(bar, 44) 27 | } 28 | 29 | say "** Test passed!" 30 | -------------------------------------------------------------------------------- /scripts/Tests/solve_lcg.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # Solve linear congruence 4 | for a in (1..10), b in (1..10), c in (1..10) { 5 | 6 | var x = solve_lcg(a,b,c) 7 | 8 | if (!x.is_nan) { 9 | assert_eq(a*x % c, b % c) 10 | assert(is_congruent(a*x, b, c), [a,b,c]) 11 | } 12 | } 13 | 14 | say ":: Test passed!" 15 | -------------------------------------------------------------------------------- /scripts/Tests/sort_disjoint_sublist.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_disjoint_sublist 5 | # 6 | 7 | func disjointSort(values, indices) { 8 | values[indices.sort...] = [values[indices...]].sort...; 9 | } 10 | 11 | var values = [7, 6, 5, 4, 3, 2, 1, 0]; 12 | var indices = [6, 1, 7]; 13 | 14 | disjointSort(values, indices); 15 | 16 | assert_eq(values, [7, 0, 5, 4, 3, 2, 1, 6]); 17 | 18 | say "** Test passed!"; 19 | -------------------------------------------------------------------------------- /scripts/Tests/sort_with_custom_cmp.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sort_using_a_custom_comparator 5 | # 6 | 7 | func mycmp(a, b) { (b.len <=> a.len) || (a.lc <=> b.lc) }; 8 | var strings = %w(Here are some sample strings to be sorted); 9 | var sorted = strings.sort(mycmp); 10 | 11 | assert_eq(sorted, ["strings", "sample", "sorted", "Here", "some", "are", "be", "to"]); 12 | 13 | say "** Test passed!"; 14 | -------------------------------------------------------------------------------- /scripts/Tests/special_methods.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Testing the '!' mark 5 | # 6 | 7 | var str = "abcdefg"; 8 | 9 | str.sub!(/^\w/,'').sub!(/\w\z/,'').sub(/\w/, '') == "cdef" || 10 | die "Error on naked method!\n"; 11 | 12 | str == 'bcdef' || 13 | die "Error on: '!'\n"; 14 | 15 | # 16 | ## More testing 17 | # 18 | 19 | str = "Sidef is working..."; 20 | str.uc!.sub(/ .*/, '') == "SIDEF" || 21 | die "Error on: ':' and '!'\n"; 22 | 23 | str.substr(-3) == '...' || 24 | die "The string had changed!\n"; 25 | 26 | # 27 | ## All done! 28 | # 29 | 30 | say "** Test passed!"; 31 | -------------------------------------------------------------------------------- /scripts/Tests/string_to_number.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var dec = '0123459'; 4 | var hex = 'abcf123'; 5 | var oct = '7651'; 6 | var bin = '101011001'; 7 | 8 | assert_eq( 123459, dec.num); 9 | assert_eq(180154659, hex.hex); 10 | assert_eq( 4009, oct.oct); 11 | assert_eq( 345, bin.bin); 12 | 13 | assert_eq("0.9054054".num, Num("0.9054054")) 14 | assert_eq("0.9054054".num, 4527027/5000000) 15 | 16 | assert_eq(%n(0.518518), [259259/500000]) 17 | assert_eq(0.518518, 259259/500000) 18 | 19 | say "** Test passed!"; 20 | -------------------------------------------------------------------------------- /scripts/Tests/strip_chars_from_str.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Strip_a_set_of_characters_from_a_string 5 | # 6 | 7 | func stripchars_1(str, char_list) { 8 | str.tr(char_list, "", "d"); 9 | } 10 | 11 | func stripchars_2(str, char_list) { 12 | str.chars.grep {|c| !char_list.contains(c)}.join; 13 | } 14 | 15 | var orig = 'She was a soul stripper. She took my heart!'; 16 | var mod = 'Sh ws soul strppr. Sh took my hrt!'; 17 | var rem = 'aei'; 18 | 19 | assert_eq(stripchars_1(orig, rem), mod); 20 | assert_eq(stripchars_2(orig, rem), mod); 21 | 22 | say "** Test passed!"; 23 | -------------------------------------------------------------------------------- /scripts/Tests/strip_non_ascii_chars.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Strip_control_codes_and_extended_characters_from_a_string 5 | # 6 | 7 | var str = "\ba\x00b\n\rc\fd\xc3\x7ffoo"; 8 | 9 | var letters = str.chars»ord()»; 10 | assert_eq(letters»chr()».join, "\ba\0b\n\rc\fd\xC3\x7Ffoo"); 11 | 12 | var nocontrols = letters.grep{ (_ > 32) && (_ != 127) }; 13 | assert_eq(nocontrols»chr()».join, "abcd\xC3foo"); 14 | 15 | var noextended = nocontrols.grep{ _ < 127 }; 16 | assert_eq(noextended»chr()».join, "abcdfoo"); 17 | 18 | say '** Test passed'; 19 | -------------------------------------------------------------------------------- /scripts/Tests/swap.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Generic_swap#Sidef 5 | # 6 | 7 | func swap_1(Ref a, Ref b) { 8 | var tmp = *a; 9 | *a = *b; 10 | *b = tmp; 11 | } 12 | 13 | func swap_2(Ref a, Ref b) { 14 | (*a, *b) = (*b, *a); 15 | } 16 | 17 | var (a, b) = ([1], [2]); 18 | swap_1(\a, \b); 19 | assert_eq(a, [2]); 20 | assert_eq(b, [1]); 21 | 22 | swap_2(\b, \a); 23 | assert_eq(a, [1]); 24 | assert_eq(b, [2]); 25 | 26 | say "** Test passed!"; 27 | -------------------------------------------------------------------------------- /scripts/Tests/sylvesters_sequence.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # See: https://en.wikipedia.org/wiki/Sylvester's_sequence 4 | 5 | func sylvesters_sequence(n, code) { 6 | 7 | var x = 1; 8 | var y = 1; 9 | 10 | { 11 | y = (x *= y); 12 | code(x += 1); 13 | } * n; 14 | 15 | return x; 16 | } 17 | 18 | sylvesters_sequence(9, func(n){say n}); 19 | -------------------------------------------------------------------------------- /scripts/Tests/symmetric_difference.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Symmetric_difference 5 | # 6 | 7 | var a = ["John", "Serena", "Bob", "Mary", "Serena"]; 8 | var b = ["Jim", "Mary", "John", "Jim", "Bob"]; 9 | var diff = (a ^ b -> unique.sort); 10 | 11 | assert_eq(diff, ["Jim", "Serena"]); 12 | 13 | say "** Test passed!"; 14 | -------------------------------------------------------------------------------- /scripts/Tests/token_recursive.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Block recursion via __BLOCK__ 5 | # 6 | 7 | { |n| 8 | n > 1 ? (__BLOCK__(n-1) * n) 9 | : 1; 10 | }(5).to_s.say; 11 | 12 | 13 | # 14 | ## Function recursion via __FUNC__ 15 | # 16 | 17 | func (n) { 18 | n > 1 ? (__FUNC__(n-2) + __FUNC__(n-1)) 19 | : (n); 20 | }(8).to_s.say; 21 | 22 | 23 | __END__ 24 | 25 | # 26 | ## Infinite block recursion 27 | # 28 | 29 | { 30 | "Hello world!".say; 31 | __BLOCK__.run; 32 | }.run; 33 | -------------------------------------------------------------------------------- /scripts/Tests/trizen_s_pair_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | for (0.to(6, 2)) {|n| 4 | var pairs = [ 5 | pow(n**2, n**2 + 1) * pow(n**2 + 1, n**2), 6 | pow(n**2 - 1, n**2) * pow(n**2, n**2 - 1), 7 | ]; 8 | 9 | "(%d, %d)\n -> %s\n -> %s\n\n".printf(n**2, n**2 - 1, pairs.map{.isqrt}...); 10 | } 11 | -------------------------------------------------------------------------------- /scripts/Tests/two_dimensional_array.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func array (x,y) { 4 | y.of { x.of{0} } 5 | } 6 | 7 | # 8 | ## Creates a two dimensional 9 | ## array with 3 rows and 3 columns 10 | # 11 | var square = array(3,3); 12 | 13 | square[1][1] = 1; 14 | square.dump.say; 15 | -------------------------------------------------------------------------------- /scripts/Tests/unary_inc_dec.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var num = 41; 4 | 5 | num++ == 41 || die 'postfix ++ error'; 6 | num == 42 || die 'postfix ++ doesn\'t work'; 7 | num-- == 42 || die 'postfix -- error'; 8 | num == 41 || die 'postfix -- doesn\'t work'; 9 | ++num == 42 || die 'prefix ++ error'; 10 | --num == 41 || die 'prefix -- error'; 11 | num == 41 || die 'final error'; 12 | 13 | say "** Test passed"; 14 | -------------------------------------------------------------------------------- /scripts/Tests/unexecuted_arguments.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | false -> 4 | && die "This should not be printed"; # not printed 5 | 6 | 7 | true -> 8 | && false -> 9 | && die "Error!"; # not printed 10 | 11 | (false || false || true) == true || die "Bool error!\n"; 12 | 13 | while (false) { 14 | die "While error!\n"; 15 | } 16 | 17 | true -> 18 | && true -> 19 | && say "** Test passed!" -> # printed 20 | && false -> 21 | && die "But failed at the end!" # not printed 22 | -------------------------------------------------------------------------------- /scripts/Tests/url_encoding_decoding.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var url = 'http://foo bar/'; 4 | 5 | func urlencode(str) { 6 | str.gsub!(%r"([^-A-Za-z0-9_.!~*'() ])", {|a| "%%%02X" % a.ord}); 7 | str.gsub!(' ', '+'); 8 | return str; 9 | } 10 | 11 | func urldecode(str) { 12 | str.gsub!('+', ' '); 13 | str.gsub!(/\%([A-Fa-f0-9]{2})/, {|a| 'C'.pack(a.hex)}); 14 | return str; 15 | } 16 | 17 | urldecode(urlencode(url)) == url || die "error!"; 18 | 19 | say "** Test passed!"; 20 | -------------------------------------------------------------------------------- /scripts/Tests/var_scoping.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var vals = [] 4 | var x = 'o'; 5 | vals << x 6 | 7 | { 8 | x.say; # o 9 | vals << x 10 | var x = 'm'; 11 | x.say; # m 12 | vals << x 13 | { 14 | x.say; # m 15 | vals << x 16 | var x = 'b'; 17 | x.say; # b 18 | vals << x 19 | }.run; 20 | x.say; # m 21 | vals << x 22 | }.run; 23 | 24 | x.say; # o 25 | vals << x 26 | 27 | assert_eq(vals, %w(o o m m b m o)) 28 | -------------------------------------------------------------------------------- /scripts/Tests/variable_references.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func assign2ref(ref, value) { 4 | *ref = value; 5 | } 6 | 7 | var x = 10; 8 | assign2ref(\x, 20); 9 | assert_eq(x, 20); 10 | 11 | say "** Test passed!"; 12 | -------------------------------------------------------------------------------- /scripts/Tests/while_loop.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## The 'while' loop: 5 | # 6 | 7 | var num = 0; 8 | while (++num <= 3) { 9 | "Hello sidef (%d)!\n".printf(num); 10 | } 11 | 12 | var i = 3 13 | 14 | while (i-- > 0) { 15 | 16 | var (*a) = (1,2,3) 17 | a.append(4) 18 | assert_eq(a, [1,2,3,4]) 19 | 20 | var (*b) = (1,2,3) 21 | b[0] = 42 22 | assert_eq(b, [42, 2, 3]) 23 | 24 | var (:h) = (a => 1, b => 2) 25 | h{:a} = 42 26 | assert_eq(h, Hash(a => 42, b => 2)) 27 | } 28 | -------------------------------------------------------------------------------- /scripts/Tests/word_processing.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var base = ('A'.ord - 1) 4 | 5 | var n = DATA.slurp.chomp.split(/\s*,\s*/) \ 6 | .map { |s| s - /"/g }.sort.uniq \ 7 | .map { |s| s.chars.sum { |sym| sym.ord - base } } \ 8 | .sum_kv { |idx, val| val * (idx+1) } 9 | 10 | assert_eq(n, 5738); 11 | say "** Test passed!"; 12 | 13 | __DATA__ 14 | "LISA","MARY","PATRICIA","LINDA","BARBARA", 15 | "MARIA","ELIZABETH","JENNIFER","MARIA","SUSAN", 16 | "MARGARET","DOROTHY","LISA","NANCY","KAREN","MARY" 17 | -------------------------------------------------------------------------------- /scripts/WWW/DNS_query.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/DNS_query 5 | # 6 | 7 | var (err, *res) = Socket.getaddrinfo( 8 | 'www.kame.net', 0, 9 | Hash.new(protocol => Socket.IPPROTO_TCP) 10 | ); 11 | err && die err; 12 | res.each { |z| 13 | say [Socket.getnameinfo(z{:addr}, Socket.NI_NUMERICHOST)][1]; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/WWW/http_tiny.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var req = require('HTTP::Tiny'); 4 | var http = req.new; 5 | 6 | var response = http.get('http://example.net'); 7 | if (!response{:success}) { 8 | "GET failed!\n".die; 9 | } 10 | 11 | say "#{response{:status}} #{response{:reason}}"; 12 | 13 | response{:headers}.each { |k,v| 14 | say "#{k}: #{v}"; 15 | } 16 | 17 | response{:content}.len && say response{:content}.len; 18 | -------------------------------------------------------------------------------- /scripts/WWW/socket_inet.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var inet = require('IO::Socket::INET'); 4 | 5 | var sock = inet.new( 6 | LocalAddr => "127.0.0.1:8080", 7 | Listen => 1, 8 | Reuse => 1, 9 | ); 10 | 11 | while (var client = sock.accept) { 12 | client.print ("HTTP/1.1 200 OK\r\n" + 13 | "Content-Type: text/html; charset=UTF-8\r\n\r\n" + 14 | "Goodbye, world!" + 15 | "Goodbye, world!\r\n"); 16 | client.close; 17 | } 18 | -------------------------------------------------------------------------------- /scripts/abstract_type.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class A { 4 | # must be filled in by the class which will inherit it 5 | method abstract() { ... }; 6 | 7 | # can be overridden in the class, but that's not mandatory 8 | method concrete() { say '# 42' }; 9 | } 10 | 11 | class SomeClass << A { 12 | method abstract() { 13 | say "# made concrete in class" 14 | } 15 | } 16 | 17 | var obj = SomeClass.new; 18 | obj.abstract(); # made concrete in class 19 | obj.concrete(); # 42 20 | -------------------------------------------------------------------------------- /scripts/accumulator_factory.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func Accumulator(sum) { 4 | func(num) { sum += num }; 5 | } 6 | 7 | var x = Accumulator(1); 8 | x.call(5); 9 | Accumulator(3); 10 | say x.call(2.3); # prints: 8.3 11 | -------------------------------------------------------------------------------- /scripts/accumulator_factory_oo.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class Accumulator (sum) { 4 | method add1(num) { 5 | sum += num; 6 | } 7 | 8 | method add2(num) { 9 | self{:sum} += num; 10 | } 11 | 12 | method add3(num) { 13 | self.sum += num; 14 | } 15 | 16 | method +(num) { 17 | self.sum = (sum + num); 18 | } 19 | } 20 | 21 | var x = Accumulator(1); 22 | 23 | x.add1(1.25); 24 | x.add2(1.875); 25 | x.add3(1.875); 26 | 27 | Accumulator(3); # create another accumulator 28 | 29 | say (x + 2.3); # prints: 8.3 30 | -------------------------------------------------------------------------------- /scripts/ackermann_function.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func A(m, n) { 4 | m == 0 ? (n + 1) 5 | : (n == 0 ? (A(m - 1, 1)) 6 | : (A(m - 1, A(m, n - 1)))); 7 | }; 8 | 9 | say A(3, 2); # prints: 29 10 | -------------------------------------------------------------------------------- /scripts/add_a_variable_to_a_class_instance_at_runtime.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class Empty{}; 4 | var e = Empty(); # create a new class instance 5 | e{:foo} = 42; # add variable 'foo' 6 | say e{:foo}; # print the value of 'foo' 7 | -------------------------------------------------------------------------------- /scripts/bernoulli_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func bernoulli_print { 4 | var a = [] 5 | range(0, 20).each { |m| 6 | a << (m+1 -> inv) 7 | m.downto(1).each { |j| 8 | (a[j-1] -= a[j]) *= j 9 | } 10 | a[0] || next 11 | printf("B(%2d) = %20s / %s\n", m, a[0].nude) 12 | } 13 | } 14 | 15 | bernoulli_print() 16 | -------------------------------------------------------------------------------- /scripts/caesar_cipher.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func caesar(msg, key, decode=false) { 4 | decode && (key = (26 - key)); 5 | msg.gsub(/([A-Z])/i, {|c| ((c.uc.ord - 65 + key) % 26) + 65 -> chr}); 6 | }; 7 | 8 | var msg = 'THE FIVE BOXING WIZARDS JUMP QUICKLY'; 9 | 10 | var enc = caesar(msg, 10); 11 | var dec = caesar(enc, 10, true); 12 | 13 | say "msg: #{msg}"; 14 | say "enc: #{enc}"; 15 | say "dec: #{dec}"; 16 | -------------------------------------------------------------------------------- /scripts/chebyshev_coefficients.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func chebft (callback, a, b, n) { 4 | 5 | var bma = (0.5 * b-a); 6 | var bpa = (0.5 * b+a); 7 | 8 | var pi_n = ((@^n »+» 0.5) »*» (Num.pi / n)); 9 | var f = (pi_n »cos»() »*» bma »+» bpa «call« callback); 10 | var sums = (@^n «run« {|i| f »*« ((pi_n »*» i) »cos»()) «+» }); 11 | 12 | sums »*» (2/n); 13 | } 14 | 15 | chebft(func(v){v.cos}, 0, 1, 10).each { |v| 16 | say ("%+.10e" % v); 17 | }; 18 | -------------------------------------------------------------------------------- /scripts/chinese_remainder_theorem.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func mul_inv(a, b) { 4 | b == 1 && return 1; 5 | var (b0, x0, x1) = (0, 0, 1); 6 | while (a > 1) { 7 | (a, b, x0, x1) = (b, a % b, x1 - x0*int(a / b), x0); 8 | }; 9 | x1 < 0 ? x1+b0 : x1; 10 | } 11 | 12 | func chinese_remainder(*n) { 13 | var N = n«*»; 14 | func (*a) { 15 | n.range.map { |i| 16 | var p = int(N / n[i]); 17 | a[i] * mul_inv(p, n[i]) * p; 18 | }.sum 19 | } 20 | } 21 | 22 | say chinese_remainder(3, 5, 7)(2, 3, 2); 23 | -------------------------------------------------------------------------------- /scripts/comb_sort.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func combSort(Array arr) { 4 | var gap = arr.len; 5 | var swaps = true; 6 | while (gap > 1 || swaps) { 7 | {gap.div!(1.25).int!} -> if (gap > 1); 8 | swaps = false; 9 | range(0, arr.end - gap) -> each { |i| 10 | if (arr[i] > arr[i+gap]) { 11 | arr[i, i+gap] = arr[i+gap, i]; 12 | swaps = true; 13 | } 14 | } 15 | } 16 | return arr; 17 | } 18 | 19 | var arr = @(1..10).shuffle; 20 | say arr; 21 | combSort(arr); 22 | say arr; 23 | -------------------------------------------------------------------------------- /scripts/combinations.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func combine(n, set) { 4 | 5 | set.len || return []; 6 | n == 1 && return set.map{[_]}; 7 | 8 | var (head, result); 9 | head = set.shift; 10 | result = __FUNC__(n-1, [set...]); 11 | 12 | result.each { |subarray| 13 | subarray.unshift(head); 14 | }; 15 | 16 | result + __FUNC__(n, set); 17 | } 18 | 19 | combine(3, @(0..4)).each {|row| 20 | say row.join(' '); 21 | } 22 | -------------------------------------------------------------------------------- /scripts/combinations_with_repetitions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func p (n, a, l) { n>0 ? (l.range.map{p(n-1, a+[l[_]], l.slice(_))}) : a }; 4 | func f (n) { n>0 ? (n * f(n - 1)) : 1 }; 5 | func n (n, m) { f(n + m - 1) / f(n) / f(m - 1) }; 6 | 7 | p(2, [], %w(iced jam plain)).each { |a| 8 | say a.map{|pair| pair.join(" ")}.join("\n"); 9 | } 10 | 11 | printf("\nThere are %d ways to pick 7 out of 10\n", n(7, 10)); 12 | -------------------------------------------------------------------------------- /scripts/currying.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Using a generic curry function: 5 | # 6 | 7 | func curry(f, *args1) { 8 | func (*args2) { 9 | f(args1..., args2...); 10 | } 11 | } 12 | 13 | func add(a, b) { 14 | a + b 15 | } 16 | 17 | var adder = curry(add, 1); 18 | say adder(3); #=>4 19 | 20 | 21 | # 22 | ## Another way, using lazy methods: 23 | # 24 | 25 | var adder2 = 1.method(:add); 26 | say adder2(3); #=> 4 27 | -------------------------------------------------------------------------------- /scripts/ethiopian_multiplication.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func double (n) { n * 2 }; 4 | func halve (n) { int(n / 2) }; 5 | 6 | func ethiopic_mult(a, b) { 7 | var r = 0; 8 | while (a > 0) { 9 | a.is_even || (r += b); 10 | a = halve(a); 11 | b = double(b); 12 | }; 13 | return r; 14 | } 15 | 16 | say ethiopic_mult(17, 34); 17 | -------------------------------------------------------------------------------- /scripts/fast_fourier_transform.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func fft(arr) { 4 | arr.len == 1 && return arr 5 | 6 | var evn = fft([arr[^arr -> grep { .is_even }]]) 7 | var odd = fft([arr[^arr -> grep { .is_odd }]]) 8 | var twd = (Num.tau.i / arr.len) 9 | 10 | ^odd -> map {|n| odd[n] *= exp(twd * n) } 11 | (evn »+« odd) + (evn »-« odd) 12 | } 13 | 14 | var cycles = 3 15 | var sequence = 0..15 16 | var wave = sequence.map {|n| sin(n * Num.tau / sequence.len * cycles) } 17 | say "wave:#{wave.map{|w| '%6.3f' % w }.join(' ')}" 18 | say "fft: #{fft(wave).map { '%6.3f' % .abs }.join(' ')}" 19 | -------------------------------------------------------------------------------- /scripts/first-class_functions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func compose(f,g) { 4 | func (*args) { 5 | f(g(args...)); 6 | } 7 | } 8 | 9 | var cube = func(a) { a.pow(3) }; 10 | var croot = func(a) { a.root(3) }; 11 | 12 | var flist1 = [Number.method(:sin), Number.method(:cos), cube]; 13 | var flist2 = [Number.method(:asin), Number.method(:acos), croot]; 14 | 15 | flist1.range.each { |i| 16 | say compose(flist1[i], flist2[i])(0.5); 17 | } 18 | -------------------------------------------------------------------------------- /scripts/functional_summation_of_fractions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Rational summation of fractions 5 | # 6 | 7 | var k = 0 # initial value of the counter 8 | 9 | func a(n) { (-1)**n } # numerator 10 | func b(n) { 2*n + 1 } # denominator 11 | 12 | func g((k)) { b(k) } 13 | func g(n) is cached { b(n) * g(n-1) } 14 | 15 | func f((k)) { a(k) } 16 | func f(n) is cached { b(n)*f(n-1) + a(n)*g(n-1) } 17 | 18 | for i in (k .. 10) { 19 | say [f(i), g(i)] 20 | } 21 | -------------------------------------------------------------------------------- /scripts/happy_numbers.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Happy_numbers 5 | # 6 | 7 | func happy(n) is cached { 8 | static seen = Hash(); 9 | 10 | return true if n.is_one; 11 | return false if seen.has_key(n); 12 | 13 | seen{n} = 1; 14 | happy(n.digits »**» 2 -> sum) 15 | } 16 | 17 | var count = 0; 18 | { |i| 19 | happy(i) ? say i : next; 20 | ++count == 8 && break; 21 | } * Inf; 22 | -------------------------------------------------------------------------------- /scripts/jensen_s_device_sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var i 4 | func sum (i, lo, hi, term) { 5 | var temp = 0 6 | for (*i = lo; *i <= hi; (*i)++) { 7 | temp += term.run 8 | } 9 | return temp; 10 | } 11 | say sum(\i, 1, 100, { 1 / i }) 12 | -------------------------------------------------------------------------------- /scripts/josephus_problem.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func josephus(n, k) { 4 | var prisoners = @^n 5 | while (prisoners.len > 1) { 6 | prisoners.rotate!(k - 1).shift 7 | } 8 | return prisoners[0] 9 | } 10 | 11 | func josephus_rec(n, k) { 12 | n == 1 ? 0 : ((__FUNC__(n-1, k) + k) % n) 13 | } 14 | 15 | var survivor1 = josephus(41, 3); 16 | say "Prisoner #{survivor1} survived."; 17 | 18 | var survivor2 = josephus_rec(41, 3); 19 | say "Prisoner #{survivor2} survived."; 20 | 21 | assert_eq(survivor1, survivor2) 22 | -------------------------------------------------------------------------------- /scripts/json.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var json = require('JSON::PP').new; 4 | 5 | # Parse JSON 6 | var data = json.decode('{"blue": [1, 2], "ocean": "water"}'); 7 | say data; 8 | 9 | # Change JSON 10 | data{:ocean} = Hash.new(water => %w[fishy salty]); 11 | 12 | # Encode JSON 13 | say json.encode(data); 14 | -------------------------------------------------------------------------------- /scripts/knuth_shuffle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Translation of: https://rosettacode.org/wiki/Knuth_shuffle#Perl 5 | # 6 | 7 | func shuffle (a) { 8 | 9 | { |n| 10 | var k = (n -> irand); 11 | k == n || (a[k, n] = a[n, k]); 12 | } * a.len; 13 | 14 | return a; 15 | } 16 | 17 | say shuffle(1..10 -> to_a); 18 | -------------------------------------------------------------------------------- /scripts/mandelbrot_set.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func mandelbrot(z) { 4 | var c = z 5 | 20.times { 6 | z = (z*z + c) 7 | z.abs > 2 && return true 8 | } 9 | return false 10 | } 11 | 12 | for y in (1 `downto` -1 `by` 0.05) { 13 | for x in (-2 `upto` 0.5 `by` 0.0315) { 14 | print(mandelbrot(Complex(x, y)) ? ' ' : '#') 15 | } 16 | print "\n" 17 | } 18 | -------------------------------------------------------------------------------- /scripts/multiple_dispatch.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func test(String a){ 4 | say "Got a string: #{a}"; 5 | } 6 | 7 | func test(Number n) { 8 | say "Got a number: #{n}"; 9 | } 10 | 11 | func test(Number n, Array m) { 12 | say "Got a number: #{n} and an array: #{m.dump}"; 13 | } 14 | 15 | func test(String s, Number p) { 16 | say "Got a string: #{s} and a number: #{p}"; 17 | } 18 | 19 | test("hello", 21); 20 | test("sidef"); 21 | test(12, [1,1]); 22 | test(42); 23 | -------------------------------------------------------------------------------- /scripts/mutual_recursion.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func F {}; 4 | func M {}; 5 | 6 | F = func(n) { n > 0 ? (n - M(F(n-1))) : 1 }; 7 | M = func(n) { n > 0 ? (n - F(M(n-1))) : 0 }; 8 | 9 | [F, M].each { |seq| 10 | (0..19).map {|i| seq.call(i)}.join(' ').say; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/permutations_iter.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func permutations(callback, arr) { 4 | var end = arr.end; 5 | var idx = arr.indices; 6 | 7 | loop { 8 | callback([arr[idx]]); 9 | 10 | var p = end; 11 | while (idx[p-1] > idx[p]) {p--}; 12 | p == 0 && return(); 13 | 14 | var d = p; 15 | idx += idx.splice(p).reverse; 16 | 17 | while (idx[p-1] > idx[d]) {d++}; 18 | idx[p-1, d] = idx[d, p-1]; 19 | } 20 | } 21 | 22 | var list = [1,2,3]; 23 | permutations({|set| say set.join }, list); 24 | -------------------------------------------------------------------------------- /scripts/permutations_rec.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func permutations(callback, set, perm=[]) { 4 | set.is_empty && callback(perm); 5 | set.range.each { |i| 6 | __FUNC__(callback, [set[(0 ..^ i)..., (i+1 ..^ set.len)...]], [perm..., set[i]]); 7 | } 8 | }; 9 | 10 | var list = [1,2,3]; 11 | permutations({|set| say set.join}, list); 12 | -------------------------------------------------------------------------------- /scripts/pythagorean_means.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func A(a) { a.sum / a.len }; 4 | func G(a) { a.prod.root(a.len) }; 5 | func H(a) { a.len / a.map{1/_}.sum }; 6 | 7 | say("A(1,...,10) = ", A(10.of{1+_})); 8 | say("G(1,...,10) = ", G(10.of{1+_})); 9 | say("H(1,...,10) = ", H(10.of{1+_})); 10 | -------------------------------------------------------------------------------- /scripts/sierpinski_carpet.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sierpinski_carpet 5 | # 6 | 7 | var c = ['##'] 8 | 3.times { 9 | c = (c.map{|x| x * 3 } + 10 | c.map{|x| x + ' '*x.len + x } + 11 | c.map{|x| x * 3 }) 12 | } 13 | say c.join("\n") 14 | -------------------------------------------------------------------------------- /scripts/sierpinski_triangle.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## https://rosettacode.org/wiki/Sierpinski_triangle 5 | # 6 | 7 | func sierpinski_triangle(n) { 8 | var triangle = ['*']; 9 | { |i| 10 | var sp = (' ' * 1< period && ( 12 | sum -= list.shift; 13 | ); 14 | return (sum / list.length); 15 | } 16 | } 17 | 18 | var ma3 = simple_moving_average(3); 19 | var ma5 = simple_moving_average(5); 20 | 21 | for num in (1..^6, 6^..1) { 22 | printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n", 23 | num, ma3.call(num), ma5.call(num)); 24 | } 25 | -------------------------------------------------------------------------------- /scripts/simple_moving_average_oo.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class sma_generator(period, list=[], sum=0) { 4 | 5 | method SMA(number) { 6 | list.append(number) 7 | sum += number 8 | list.len > period && ( 9 | sum -= list.shift; 10 | ) 11 | return (sum / list.len) 12 | } 13 | } 14 | 15 | var ma3 = sma_generator(3) 16 | var ma5 = sma_generator(5) 17 | 18 | for num in (1..^6, 6^..1) { 19 | printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n", 20 | num, ma3.SMA(num), ma5.SMA(num)) 21 | } 22 | -------------------------------------------------------------------------------- /scripts/symmetric_summation_of_fractions.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | class MyFraction(num, den) { 4 | 5 | method +(MyFraction arg) { 6 | MyFraction( 7 | self.num*arg.den + arg.num*self.den, 8 | self.den*arg.den 9 | ) 10 | } 11 | 12 | method to_s { 13 | "[#{num}, #{den}]" 14 | } 15 | } 16 | 17 | func num(n) { n**0 } 18 | func den(n) { n**2 } 19 | 20 | var from = 1 21 | var to = 10 22 | 23 | var sum = MyFraction(0, 1) 24 | for i in (from .. to) { 25 | sum += MyFraction(num(i), den(i)) 26 | say sum 27 | } 28 | -------------------------------------------------------------------------------- /scripts/variadic_function.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func print_all(*things) { 4 | things.each { |x| say x }; 5 | }; 6 | 7 | print_all("Rosetta", "Code", "Is", "Awesome!"); 8 | -------------------------------------------------------------------------------- /scripts/vigenere_cipher.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | func s2v(s) { s.uc.scan(/[A-Z]/)»ord»() »-» 65 }; 4 | func v2s(v) { (v »%» 26 »+» 65)»chr»() -> join }; 5 | 6 | func blacken (red, key) { v2s(s2v(red) »+« s2v(key)) }; 7 | func redden (blk, key) { v2s(s2v(blk) »-« s2v(key)) }; 8 | 9 | var red = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; 10 | var key = "Vigenere Cipher!!!"; 11 | 12 | say red; 13 | say (var black = blacken(red, key)); 14 | say redden(black, key); 15 | -------------------------------------------------------------------------------- /scripts/y_combinator.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | var y = ->(f) {->(g) {g(g)}(->(g) { f(->(*args) {g(g)(args...)})})}; 4 | 5 | var fac = ->(f) { ->(n) { n < 2 ? 1 : (n * f(n-1)) } }; 6 | say 10.of { |i| y(fac)(i) }; 7 | 8 | var fib = ->(f) { ->(n) { n < 2 ? n : (f(n-2) + f(n-1)) } }; 9 | say 10.of { |i| y(fib)(i) }; 10 | -------------------------------------------------------------------------------- /scripts/zeta_2n.sf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # 4 | ## Closed-form for Zeta(2n) 5 | # 6 | 7 | # See also: https://en.wikipedia.org/wiki/Riemann_zeta_function 8 | 9 | func bernoulli_number(n) is cached { 10 | 11 | n.is_one && return 1/2 12 | n.is_odd && return 0 13 | 14 | ^n -> reduce({|a, k| a - (__FUNC__(k) * binomial(n, k) / (n - k + 1))}, 1) 15 | } 16 | 17 | func zeta_2n(Number n {.is_even}) { 18 | ((-1)**(n/2 + 1) * 2**(n - 1) * Num.pi**n * bernoulli_number(n)) / n! 19 | } 20 | 21 | for n in (1 .. 10) { 22 | say "zeta(#{2*n}) = #{zeta_2n(2*n)}" 23 | } 24 | -------------------------------------------------------------------------------- /t/00-load.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | use 5.006; 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | 7 | plan tests => 1; 8 | 9 | BEGIN { 10 | use_ok('Sidef') || print "Bail out!\n"; 11 | } 12 | 13 | diag("Testing Sidef $Sidef::VERSION, Perl $], $^X"); 14 | -------------------------------------------------------------------------------- /t/currying.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use utf8; 4 | use 5.006; 5 | use strict; 6 | use warnings; 7 | use Test::More; 8 | 9 | plan tests => 1; 10 | 11 | use Sidef; 12 | 13 | my $code = <<'EOT'; 14 | 15 | func curry(f, *args1) { 16 | func (*args2) { 17 | f(args1..., args2...); 18 | } 19 | } 20 | 21 | func add(a, b) { 22 | a + b 23 | } 24 | 25 | var adder = curry(add, 13); 26 | adder(29); 27 | 28 | EOT 29 | 30 | my $sidef = Sidef->new(name => 'currying'); 31 | my $result = $sidef->execute_code($code); 32 | 33 | is("$result", "42"); 34 | -------------------------------------------------------------------------------- /t/eval.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use utf8; 4 | use 5.006; 5 | use strict; 6 | use warnings; 7 | use Test::More; 8 | 9 | plan tests => 1; 10 | 11 | use Sidef; 12 | 13 | my $code = <<'EOT'; 14 | 15 | func eval_with_x(code, x, y) { 16 | var f = eval(code); 17 | x = y; 18 | eval(code) - f; 19 | } 20 | 21 | eval_with_x('2 ** x', 3, 5) # should be: "24" 22 | 23 | EOT 24 | 25 | my $sidef = Sidef->new(name => 'eval'); 26 | my $result = $sidef->execute_code($code); 27 | 28 | is("$result", "24"); 29 | -------------------------------------------------------------------------------- /t/pod.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use 5.006; 4 | use strict; 5 | use warnings; 6 | use Test::More; 7 | 8 | # Ensure a recent version of Test::Pod 9 | my $min_tp = 1.22; 10 | eval "use Test::Pod $min_tp"; 11 | plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; 12 | 13 | all_pod_files_ok(); 14 | -------------------------------------------------------------------------------- /utils/Web interface/css/main.css: -------------------------------------------------------------------------------- 1 | pre { 2 | padding: 0.1em 0.5em 0.3em 0.7em; 3 | border-left: 11px solid #ccc; 4 | margin: 1.7em 0 1.7em 0.3em; 5 | overflow: auto; 6 | width: 93%; 7 | } 8 | -------------------------------------------------------------------------------- /utils/Web interface/js/main.js: -------------------------------------------------------------------------------- 1 | function clearContents(element) { 2 | if (element.value == 'Write your code here...') { 3 | element.value = "#!/usr/bin/sidef\n\n"; 4 | } 5 | } 6 | 7 | $(document).ready(function(){ 8 | var tabby_opts = {tabString:' '}; 9 | $('textarea').tabby(tabby_opts); 10 | }); 11 | -------------------------------------------------------------------------------- /utils/auto_perltidy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | alias perltidy='perltidy -utf8 -l=160 -f -kbl=1 -bbb -bbc -bbs -b -ple -bt=2 -pt=2 -sbt=2 -bvt=0 -sbvt=1 -cti=1 -bar -lp -anl'; 4 | which perltidy; 5 | cd ..; 6 | for i in $(git status | grep '^[[:cntrl:]]*modified:' | grep -E 'bin/|\.(pm|t)$' | perl -nE 'say +(split)[-1]'); do echo $i; perltidy -b $i; done 7 | -------------------------------------------------------------------------------- /utils/bak_cleaner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in $(git status | grep \.bak$ | perl -nE 'say +(split)[-1]'); do echo $i; rm $i; done 4 | -------------------------------------------------------------------------------- /utils/grep_errors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | perl -W ../bin/sidef -t "$@" 2> /tmp/errors-$$.txt 4 | cat /tmp/errors-$$.txt | egrep '\b(Sidef|sidef)\b' | grep -v ' redefined at ' | grep -v '^Deep recursion ' | grep -v '^Prototype mismatch' | grep -v ' used only once ' | grep -v '^Useless use of a constant' 5 | rm /tmp/errors-$$.txt 6 | --------------------------------------------------------------------------------